[media] gspca - ov519: Re-initialize the webcam at resume time
[pandora-kernel.git] / drivers / media / video / gspca / ov519.c
index 6cf6855..08f07c3 100644 (file)
@@ -75,7 +75,7 @@ struct sd {
 
        struct gspca_ctrl ctrls[NCTRL];
 
-       __u8 packet_nr;
+       u8 packet_nr;
 
        char bridge;
 #define BRIDGE_OV511           0
@@ -94,42 +94,43 @@ struct sd {
        char snapshot_needs_reset;
 
        /* Determined by sensor type */
-       __u8 sif;
+       u8 sif;
 
-       __u8 quality;
+       u8 quality;
 #define QUALITY_MIN 50
 #define QUALITY_MAX 70
 #define QUALITY_DEF 50
 
-       __u8 stopped;           /* Streaming is temporarily paused */
-       __u8 first_frame;
-
-       __u8 frame_rate;        /* current Framerate */
-       __u8 clockdiv;          /* clockdiv override */
-
-       char sensor;            /* Type of image sensor chip (SEN_*) */
-#define SEN_UNKNOWN 0
-#define SEN_OV2610 1
-#define SEN_OV3610 2
-#define SEN_OV6620 3
-#define SEN_OV6630 4
-#define SEN_OV66308AF 5
-#define SEN_OV7610 6
-#define SEN_OV7620 7
-#define SEN_OV7620AE 8
-#define SEN_OV7640 9
-#define SEN_OV7648 10
-#define SEN_OV7670 11
-#define SEN_OV76BE 12
-#define SEN_OV8610 13
+       u8 stopped;             /* Streaming is temporarily paused */
+       u8 first_frame;
+
+       u8 frame_rate;          /* current Framerate */
+       u8 clockdiv;            /* clockdiv override */
+
+       s8 sensor;              /* Type of image sensor chip (SEN_*) */
 
        u8 sensor_addr;
-       int sensor_width;
-       int sensor_height;
-       int sensor_reg_cache[256];
+       u16 sensor_width;
+       u16 sensor_height;
+       s16 sensor_reg_cache[256];
 
        u8 jpeg_hdr[JPEG_HDR_SZ];
 };
+enum sensors {
+       SEN_OV2610,
+       SEN_OV3610,
+       SEN_OV6620,
+       SEN_OV6630,
+       SEN_OV66308AF,
+       SEN_OV7610,
+       SEN_OV7620,
+       SEN_OV7620AE,
+       SEN_OV7640,
+       SEN_OV7648,
+       SEN_OV7670,
+       SEN_OV76BE,
+       SEN_OV8610,
+};
 
 /* Note this is a bit of a hack, but the w9968cf driver needs the code for all
    the ov sensors which is already present here. When we have the time we
@@ -225,7 +226,7 @@ static const struct ctrl sd_ctrls[] = {
                .type    = V4L2_CTRL_TYPE_MENU,
                .name    = "Light frequency filter",
                .minimum = 0,
-               .maximum = 2,   /* 0: 0, 1: 50Hz, 2:60Hz */
+               .maximum = 2,   /* 0: no flicker, 1: 50Hz, 2:60Hz, 3: auto */
                .step    = 1,
                .default_value = 0,
            },
@@ -233,6 +234,51 @@ static const struct ctrl sd_ctrls[] = {
        },
 };
 
+/* table of the disabled controls */
+static const unsigned ctrl_dis[] = {
+[SEN_OV2610] =         (1 << NCTRL) - 1,       /* no control */
+
+[SEN_OV3610] =         (1 << NCTRL) - 1,       /* no control */
+
+[SEN_OV6620] =         (1 << HFLIP) |
+                       (1 << VFLIP),
+
+[SEN_OV6630] =         (1 << HFLIP) |
+                       (1 << VFLIP),
+
+[SEN_OV66308AF] =      (1 << HFLIP) |
+                       (1 << VFLIP),
+
+[SEN_OV7610] =         (1 << HFLIP) |
+                       (1 << VFLIP),
+
+[SEN_OV7620] =         (1 << HFLIP) |
+                       (1 << VFLIP),
+
+[SEN_OV7620AE] =       (1 << HFLIP) |
+                       (1 << VFLIP),
+
+[SEN_OV7640] =         (1 << HFLIP) |
+                       (1 << VFLIP) |
+                       (1 << AUTOBRIGHT) |
+                       (1 << CONTRAST),
+
+[SEN_OV7648] =         (1 << HFLIP) |
+                       (1 << VFLIP) |
+                       (1 << AUTOBRIGHT) |
+                       (1 << CONTRAST),
+
+[SEN_OV7670] =         (1 << COLORS) |
+                       (1 << AUTOBRIGHT),
+
+[SEN_OV76BE] =         (1 << HFLIP) |
+                       (1 << VFLIP),
+
+[SEN_OV8610] =         (1 << HFLIP) |
+                       (1 << VFLIP) |
+                       (1 << FREQ),
+};
+
 static const struct v4l2_pix_format ov519_vga_mode[] = {
        {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
                .bytesperline = 320,
@@ -412,7 +458,6 @@ static const struct v4l2_pix_format ovfx2_ov3610_mode[] = {
                .priv = 0},
 };
 
-
 /* Registers common to OV511 / OV518 */
 #define R51x_FIFO_PSIZE                        0x30    /* 2 bytes wide w/ OV518(+) */
 #define R51x_SYS_RESET                 0x50
@@ -420,7 +465,7 @@ static const struct v4l2_pix_format ovfx2_ov3610_mode[] = {
        #define OV511_RESET_OMNICE      0x08
 #define R51x_SYS_INIT                  0x53
 #define R51x_SYS_SNAP                  0x52
-#define R51x_SYS_CUST_ID               0x5F
+#define R51x_SYS_CUST_ID               0x5f
 #define R51x_COMP_LUT_BEGIN            0x80
 
 /* OV511 Camera interface register numbers */
@@ -435,13 +480,13 @@ static const struct v4l2_pix_format ovfx2_ov3610_mode[] = {
 #define R511_CAM_OPTS                  0x18
 
 #define R511_SNAP_FRAME                        0x19
-#define R511_SNAP_PXCNT                        0x1A
-#define R511_SNAP_LNCNT                        0x1B
-#define R511_SNAP_PXDIV                        0x1C
-#define R511_SNAP_LNDIV                        0x1D
-#define R511_SNAP_UV_EN                        0x1E
-#define R511_SNAP_UV_EN                        0x1E
-#define R511_SNAP_OPTS                 0x1F
+#define R511_SNAP_PXCNT                        0x1a
+#define R511_SNAP_LNCNT                        0x1b
+#define R511_SNAP_PXDIV                        0x1c
+#define R511_SNAP_LNDIV                        0x1d
+#define R511_SNAP_UV_EN                        0x1e
+#define R511_SNAP_UV_EN                        0x1e
+#define R511_SNAP_OPTS                 0x1f
 
 #define R511_DRAM_FLOW_CTL             0x20
 #define R511_FIFO_OPTS                 0x31
@@ -466,13 +511,14 @@ static const struct v4l2_pix_format ovfx2_ov3610_mode[] = {
 #define OV519_R25_FORMAT               0x25
 
 /* OV519 System Controller register numbers */
-#define OV519_SYS_RESET1 0x51
-#define OV519_SYS_EN_CLK1 0x54
+#define OV519_R51_RESET1               0x51
+#define OV519_R54_EN_CLK1              0x54
+#define OV519_R57_SNAPSHOT             0x57
 
 #define OV519_GPIO_DATA_OUT0           0x71
 #define OV519_GPIO_IO_CTRL0            0x72
 
-#define OV511_ENDPOINT_ADDRESS  1      /* Isoc endpoint number */
+/*#define OV511_ENDPOINT_ADDRESS 1      * Isoc endpoint number */
 
 /*
  * The FX2 chip does not give us a zero length read at end of frame.
@@ -527,79 +573,79 @@ static const struct v4l2_pix_format ovfx2_ov3610_mode[] = {
 #define OV7610_REG_COM_I       0x29    /* misc settings */
 
 /* OV7670 registers */
-#define OV7670_REG_GAIN        0x00    /* Gain lower 8 bits (rest in vref) */
-#define OV7670_REG_BLUE        0x01    /* blue gain */
-#define OV7670_REG_RED         0x02    /* red gain */
-#define OV7670_REG_VREF        0x03    /* Pieces of GAIN, VSTART, VSTOP */
-#define OV7670_REG_COM1        0x04    /* Control 1 */
-#define OV7670_REG_AECHH       0x07    /* AEC MS 5 bits */
-#define OV7670_REG_COM3        0x0c    /* Control 3 */
-#define OV7670_REG_COM4        0x0d    /* Control 4 */
-#define OV7670_REG_COM5        0x0e    /* All "reserved" */
-#define OV7670_REG_COM6        0x0f    /* Control 6 */
-#define OV7670_REG_AECH        0x10    /* More bits of AEC value */
-#define OV7670_REG_CLKRC       0x11    /* Clock control */
-#define OV7670_REG_COM7        0x12    /* Control 7 */
-#define   OV7670_COM7_FMT_VGA    0x00
-#define   OV7670_COM7_YUV        0x00    /* YUV */
-#define   OV7670_COM7_FMT_QVGA   0x10    /* QVGA format */
-#define   OV7670_COM7_FMT_MASK   0x38
-#define   OV7670_COM7_RESET      0x80    /* Register reset */
-#define OV7670_REG_COM8        0x13    /* Control 8 */
-#define   OV7670_COM8_AEC        0x01    /* Auto exposure enable */
-#define   OV7670_COM8_AWB        0x02    /* White balance enable */
-#define   OV7670_COM8_AGC        0x04    /* Auto gain enable */
-#define   OV7670_COM8_BFILT      0x20    /* Band filter enable */
-#define   OV7670_COM8_AECSTEP    0x40    /* Unlimited AEC step size */
-#define   OV7670_COM8_FASTAEC    0x80    /* Enable fast AGC/AEC */
-#define OV7670_REG_COM9        0x14    /* Control 9  - gain ceiling */
-#define OV7670_REG_COM10       0x15    /* Control 10 */
-#define OV7670_REG_HSTART      0x17    /* Horiz start high bits */
-#define OV7670_REG_HSTOP       0x18    /* Horiz stop high bits */
-#define OV7670_REG_VSTART      0x19    /* Vert start high bits */
-#define OV7670_REG_VSTOP       0x1a    /* Vert stop high bits */
-#define OV7670_REG_MVFP        0x1e    /* Mirror / vflip */
-#define   OV7670_MVFP_VFLIP     0x10    /* vertical flip */
-#define   OV7670_MVFP_MIRROR     0x20    /* Mirror image */
-#define OV7670_REG_AEW         0x24    /* AGC upper limit */
-#define OV7670_REG_AEB         0x25    /* AGC lower limit */
-#define OV7670_REG_VPT         0x26    /* AGC/AEC fast mode op region */
-#define OV7670_REG_HREF        0x32    /* HREF pieces */
-#define OV7670_REG_TSLB        0x3a    /* lots of stuff */
-#define OV7670_REG_COM11       0x3b    /* Control 11 */
-#define   OV7670_COM11_EXP       0x02
-#define   OV7670_COM11_HZAUTO    0x10    /* Auto detect 50/60 Hz */
-#define OV7670_REG_COM12       0x3c    /* Control 12 */
-#define OV7670_REG_COM13       0x3d    /* Control 13 */
-#define   OV7670_COM13_GAMMA     0x80    /* Gamma enable */
-#define   OV7670_COM13_UVSAT     0x40    /* UV saturation auto adjustment */
-#define OV7670_REG_COM14       0x3e    /* Control 14 */
-#define OV7670_REG_EDGE        0x3f    /* Edge enhancement factor */
-#define OV7670_REG_COM15       0x40    /* Control 15 */
-#define   OV7670_COM15_R00FF     0xc0    /*            00 to FF */
-#define OV7670_REG_COM16       0x41    /* Control 16 */
-#define   OV7670_COM16_AWBGAIN   0x08    /* AWB gain enable */
-#define OV7670_REG_BRIGHT      0x55    /* Brightness */
-#define OV7670_REG_CONTRAS     0x56    /* Contrast control */
-#define OV7670_REG_GFIX        0x69    /* Fix gain control */
-#define OV7670_REG_RGB444      0x8c    /* RGB 444 control */
-#define OV7670_REG_HAECC1      0x9f    /* Hist AEC/AGC control 1 */
-#define OV7670_REG_HAECC2      0xa0    /* Hist AEC/AGC control 2 */
-#define OV7670_REG_BD50MAX     0xa5    /* 50hz banding step limit */
-#define OV7670_REG_HAECC3      0xa6    /* Hist AEC/AGC control 3 */
-#define OV7670_REG_HAECC4      0xa7    /* Hist AEC/AGC control 4 */
-#define OV7670_REG_HAECC5      0xa8    /* Hist AEC/AGC control 5 */
-#define OV7670_REG_HAECC6      0xa9    /* Hist AEC/AGC control 6 */
-#define OV7670_REG_HAECC7      0xaa    /* Hist AEC/AGC control 7 */
-#define OV7670_REG_BD60MAX     0xab    /* 60hz banding step limit */
+#define OV7670_R00_GAIN                0x00    /* Gain lower 8 bits (rest in vref) */
+#define OV7670_R01_BLUE                0x01    /* blue gain */
+#define OV7670_R02_RED         0x02    /* red gain */
+#define OV7670_R03_VREF                0x03    /* Pieces of GAIN, VSTART, VSTOP */
+#define OV7670_R04_COM1                0x04    /* Control 1 */
+/*#define OV7670_R07_AECHH     0x07     * AEC MS 5 bits */
+#define OV7670_R0C_COM3                0x0c    /* Control 3 */
+#define OV7670_R0D_COM4                0x0d    /* Control 4 */
+#define OV7670_R0E_COM5                0x0e    /* All "reserved" */
+#define OV7670_R0F_COM6                0x0f    /* Control 6 */
+#define OV7670_R10_AECH                0x10    /* More bits of AEC value */
+#define OV7670_R11_CLKRC       0x11    /* Clock control */
+#define OV7670_R12_COM7                0x12    /* Control 7 */
+#define   OV7670_COM7_FMT_VGA   0x00
+/*#define   OV7670_COM7_YUV     0x00    * YUV */
+#define   OV7670_COM7_FMT_QVGA  0x10   /* QVGA format */
+#define   OV7670_COM7_FMT_MASK  0x38
+#define   OV7670_COM7_RESET     0x80   /* Register reset */
+#define OV7670_R13_COM8                0x13    /* Control 8 */
+#define   OV7670_COM8_AEC       0x01   /* Auto exposure enable */
+#define   OV7670_COM8_AWB       0x02   /* White balance enable */
+#define   OV7670_COM8_AGC       0x04   /* Auto gain enable */
+#define   OV7670_COM8_BFILT     0x20   /* Band filter enable */
+#define   OV7670_COM8_AECSTEP   0x40   /* Unlimited AEC step size */
+#define   OV7670_COM8_FASTAEC   0x80   /* Enable fast AGC/AEC */
+#define OV7670_R14_COM9                0x14    /* Control 9 - gain ceiling */
+#define OV7670_R15_COM10       0x15    /* Control 10 */
+#define OV7670_R17_HSTART      0x17    /* Horiz start high bits */
+#define OV7670_R18_HSTOP       0x18    /* Horiz stop high bits */
+#define OV7670_R19_VSTART      0x19    /* Vert start high bits */
+#define OV7670_R1A_VSTOP       0x1a    /* Vert stop high bits */
+#define OV7670_R1E_MVFP                0x1e    /* Mirror / vflip */
+#define   OV7670_MVFP_VFLIP     0x10   /* vertical flip */
+#define   OV7670_MVFP_MIRROR    0x20   /* Mirror image */
+#define OV7670_R24_AEW         0x24    /* AGC upper limit */
+#define OV7670_R25_AEB         0x25    /* AGC lower limit */
+#define OV7670_R26_VPT         0x26    /* AGC/AEC fast mode op region */
+#define OV7670_R32_HREF                0x32    /* HREF pieces */
+#define OV7670_R3A_TSLB                0x3a    /* lots of stuff */
+#define OV7670_R3B_COM11       0x3b    /* Control 11 */
+#define   OV7670_COM11_EXP      0x02
+#define   OV7670_COM11_HZAUTO   0x10   /* Auto detect 50/60 Hz */
+#define OV7670_R3C_COM12       0x3c    /* Control 12 */
+#define OV7670_R3D_COM13       0x3d    /* Control 13 */
+#define   OV7670_COM13_GAMMA    0x80   /* Gamma enable */
+#define   OV7670_COM13_UVSAT    0x40   /* UV saturation auto adjustment */
+#define OV7670_R3E_COM14       0x3e    /* Control 14 */
+#define OV7670_R3F_EDGE                0x3f    /* Edge enhancement factor */
+#define OV7670_R40_COM15       0x40    /* Control 15 */
+/*#define   OV7670_COM15_R00FF  0xc0    *      00 to FF */
+#define OV7670_R41_COM16       0x41    /* Control 16 */
+#define   OV7670_COM16_AWBGAIN  0x08   /* AWB gain enable */
+#define OV7670_R55_BRIGHT      0x55    /* Brightness */
+#define OV7670_R56_CONTRAS     0x56    /* Contrast control */
+#define OV7670_R69_GFIX                0x69    /* Fix gain control */
+/*#define OV7670_R8C_RGB444    0x8c     * RGB 444 control */
+#define OV7670_R9F_HAECC1      0x9f    /* Hist AEC/AGC control 1 */
+#define OV7670_RA0_HAECC2      0xa0    /* Hist AEC/AGC control 2 */
+#define OV7670_RA5_BD50MAX     0xa5    /* 50hz banding step limit */
+#define OV7670_RA6_HAECC3      0xa6    /* Hist AEC/AGC control 3 */
+#define OV7670_RA7_HAECC4      0xa7    /* Hist AEC/AGC control 4 */
+#define OV7670_RA8_HAECC5      0xa8    /* Hist AEC/AGC control 5 */
+#define OV7670_RA9_HAECC6      0xa9    /* Hist AEC/AGC control 6 */
+#define OV7670_RAA_HAECC7      0xaa    /* Hist AEC/AGC control 7 */
+#define OV7670_RAB_BD60MAX     0xab    /* 60hz banding step limit */
 
 struct ov_regvals {
-       __u8 reg;
-       __u8 val;
+       u8 reg;
+       u8 val;
 };
 struct ov_i2c_regvals {
-       __u8 reg;
-       __u8 val;
+       u8 reg;
+       u8 val;
 };
 
 /* Settings for OV2610 camera chip */
@@ -617,7 +663,6 @@ static const struct ov_i2c_regvals norm_3620b[] = {
         * "wait 4096 external clock ... to make sure the sensor is
         * stable and ready to access registers" i.e. 160us at 24MHz
         */
-
        { 0x12, 0x80 }, /* COMH reset */
        { 0x12, 0x00 }, /* QXGA, master */
 
@@ -650,7 +695,7 @@ static const struct ov_i2c_regvals norm_3620b[] = {
         *    COMI[0] "Exposure control"
         *                  =   0 (0x00) .......0 "Manual"
         */
-       { 0x13, 0xC0 },
+       { 0x13, 0xc0 },
 
        /*
         * 09 COMC "Common Control C"
@@ -706,7 +751,7 @@ static const struct ov_i2c_regvals norm_3620b[] = {
         *    COME[0] "Auto zero circuit select"
         *                  =   1 (0x01) .......1 "On"
         */
-       { 0x0d, 0xA1 },
+       { 0x0d, 0xa1 },
 
        /*
         * 0E COMF "Common Control F"
@@ -770,7 +815,7 @@ static const struct ov_i2c_regvals norm_3620b[] = {
         *    COMJ[0] "Reserved"
         *                  =   0 (0x00) .......0
         */
-       { 0x14, 0xC6 },
+       { 0x14, 0xc6 },
 
        /*
         * 15 COMK "Common Control K"
@@ -876,7 +921,7 @@ static const struct ov_i2c_regvals norm_3620b[] = {
         *    FVOPT[7:0] "Range"
         *                  =  31 (0x1F) 00011111
         */
-       { 0x3c, 0x1F },
+       { 0x3c, 0x1f },
 
        /*
         * 44 Undocumented  =   0 (0x00) 00000000
@@ -925,7 +970,7 @@ static const struct ov_i2c_regvals norm_3620b[] = {
         *    48[7:0] "It's a secret"
         *                  = 192 (0xC0) 11000000
         */
-       { 0x48, 0xC0 },
+       { 0x48, 0xc0 },
 
        /*
         * 49 Undocumented  =  25 (0x19) 00011001
@@ -939,18 +984,18 @@ static const struct ov_i2c_regvals norm_3620b[] = {
         *    4B[7:0] "It's a secret"
         *                  = 128 (0x80) 10000000
         */
-       { 0x4B, 0x80 },
+       { 0x4b, 0x80 },
 
        /*
         * 4D Undocumented  = 196 (0xC4) 11000100
         *    4D[7:0] "It's a secret"
         *                  = 196 (0xC4) 11000100
         */
-       { 0x4D, 0xC4 },
+       { 0x4d, 0xc4 },
 
        /*
         * 35 VREF "Reference Voltage Control"
-        *                  =  76 (0x4C) 01001100
+        *                  =  76 (0x4c) 01001100
         *    VREF[7:5] "Column high reference control"
         *                  =   2 (0x02) 010..... "higher voltage"
         *    VREF[4:2] "Column low reference control"
@@ -958,21 +1003,21 @@ static const struct ov_i2c_regvals norm_3620b[] = {
         *    VREF[1:0] "Reserved"
         *                  =   0 (0x00) ......00
         */
-       { 0x35, 0x4C },
+       { 0x35, 0x4c },
 
        /*
         * 3D Undocumented  =   0 (0x00) 00000000
         *    3D[7:0] "It's a secret"
         *                  =   0 (0x00) 00000000
         */
-       { 0x3D, 0x00 },
+       { 0x3d, 0x00 },
 
        /*
         * 3E Undocumented  =   0 (0x00) 00000000
         *    3E[7:0] "It's a secret"
         *                  =   0 (0x00) 00000000
         */
-       { 0x3E, 0x00 },
+       { 0x3e, 0x00 },
 
        /*
         * 3B FREFB "Internal Reference Adjustment"
@@ -1012,7 +1057,7 @@ static const struct ov_i2c_regvals norm_3620b[] = {
         *    VBLM[3:0] "Sensor current control"
         *                  =  10 (0x0A) ....1010
         */
-       { 0x34, 0x5A },
+       { 0x34, 0x5a },
 
        /*
         * 3B FREFB "Internal Reference Adjustment"
@@ -1078,7 +1123,7 @@ static const struct ov_i2c_regvals norm_3620b[] = {
         *    HREFST[7:0] "Horizontal window start, 8 MSBs"
         *                  =  31 (0x1F) 00011111
         */
-       { 0x17, 0x1F },
+       { 0x17, 0x1f },
 
        /*
         * 18 HREFEND "Horizontal window end"
@@ -1086,7 +1131,7 @@ static const struct ov_i2c_regvals norm_3620b[] = {
         *    HREFEND[7:0] "Horizontal Window End, 8 MSBs"
         *                  =  95 (0x5F) 01011111
         */
-       { 0x18, 0x5F },
+       { 0x18, 0x5f },
 
        /*
         * 19 VSTRT "Vertical window start"
@@ -1126,7 +1171,7 @@ static const struct ov_i2c_regvals norm_3620b[] = {
         *    COMA[1:0] "Vertical window start line control 2 LSBs"
         *                  =   2 (0x02) ......10
         */
-       { 0x03, 0x4A },
+       { 0x03, 0x4a },
 
        /*
         * 11 CLKRC "Clock Rate Control"
@@ -1183,7 +1228,7 @@ static const struct ov_i2c_regvals norm_3620b[] = {
         *    HREFST[7:0] "Horizontal window start, 8 MSBs"
         *                  =  31 (0x1F) 00011111
         */
-       { 0x17, 0x1F },
+       { 0x17, 0x1f },
 
        /*
         * 18 HREFEND "Horizontal window end"
@@ -1191,7 +1236,7 @@ static const struct ov_i2c_regvals norm_3620b[] = {
         *    HREFEND[7:0] "Horizontal Window End, 8 MSBs"
         *                  =  95 (0x5F) 01011111
         */
-       { 0x18, 0x5F },
+       { 0x18, 0x5f },
 
        /*
         * 19 VSTRT "Vertical window start"
@@ -1231,7 +1276,7 @@ static const struct ov_i2c_regvals norm_3620b[] = {
         *    COMA[1:0] "Vertical window start line control 2 LSBs"
         *                  =   2 (0x02) ......10
         */
-       { 0x03, 0x4A },
+       { 0x03, 0x4a },
 
        /*
         * 02 RED "Red Gain Control"
@@ -1241,7 +1286,7 @@ static const struct ov_i2c_regvals norm_3620b[] = {
         *    RED[6:0] "Value"
         *                  =  47 (0x2F) .0101111
         */
-       { 0x02, 0xAF },
+       { 0x02, 0xaf },
 
        /*
         * 2D ADDVSL "VSYNC Pulse Width"
@@ -1249,7 +1294,7 @@ static const struct ov_i2c_regvals norm_3620b[] = {
         *    ADDVSL[7:0] "VSYNC pulse width, LSB"
         *                  = 210 (0xD2) 11010010
         */
-       { 0x2d, 0xD2 },
+       { 0x2d, 0xd2 },
 
        /*
         * 00 GAIN          =  24 (0x18) 00011000
@@ -1272,7 +1317,7 @@ static const struct ov_i2c_regvals norm_3620b[] = {
         *    BLUE[6:0] "Value"
         *                  = 112 (0x70) .1110000
         */
-       { 0x01, 0xF0 },
+       { 0x01, 0xf0 },
 
        /*
         * 10 AEC "Automatic Exposure Control"
@@ -1280,14 +1325,14 @@ static const struct ov_i2c_regvals norm_3620b[] = {
         *    AEC[7:0] "Automatic Exposure Control, 8 MSBs"
         *                  =  10 (0x0A) 00001010
         */
-       { 0x10, 0x0A },
-
-       { 0xE1, 0x67 },
-       { 0xE3, 0x03 },
-       { 0xE4, 0x26 },
-       { 0xE5, 0x3E },
-       { 0xF8, 0x01 },
-       { 0xFF, 0x01 },
+       { 0x10, 0x0a },
+
+       { 0xe1, 0x67 },
+       { 0xe3, 0x03 },
+       { 0xe4, 0x26 },
+       { 0xe5, 0x3e },
+       { 0xf8, 0x01 },
+       { 0xff, 0x01 },
 };
 
 static const struct ov_i2c_regvals norm_6x20[] = {
@@ -1296,7 +1341,7 @@ static const struct ov_i2c_regvals norm_6x20[] = {
        { 0x03, 0x60 },
        { 0x05, 0x7f }, /* For when autoadjust is off */
        { 0x07, 0xa8 },
-       /* The ratio of 0x0c and 0x0d  controls the white point */
+       /* The ratio of 0x0c and 0x0d controls the white point */
        { 0x0c, 0x24 },
        { 0x0d, 0x24 },
        { 0x0f, 0x15 }, /* COMS */
@@ -1464,7 +1509,7 @@ static const struct ov_i2c_regvals norm_7620[] = {
        { 0x00, 0x00 },         /* gain */
        { 0x01, 0x80 },         /* blue gain */
        { 0x02, 0x80 },         /* red gain */
-       { 0x03, 0xc0 },         /* OV7670_REG_VREF */
+       { 0x03, 0xc0 },         /* OV7670_R03_VREF */
        { 0x06, 0x60 },
        { 0x07, 0x00 },
        { 0x0c, 0x24 },
@@ -1535,30 +1580,30 @@ static const struct ov_i2c_regvals norm_7640[] = {
 /* 7670. Defaults taken from OmniVision provided data,
 *  as provided by Jonathan Corbet of OLPC              */
 static const struct ov_i2c_regvals norm_7670[] = {
-       { OV7670_REG_COM7, OV7670_COM7_RESET },
-       { OV7670_REG_TSLB, 0x04 },              /* OV */
-       { OV7670_REG_COM7, OV7670_COM7_FMT_VGA }, /* VGA */
-       { OV7670_REG_CLKRC, 0x01 },
+       { OV7670_R12_COM7, OV7670_COM7_RESET },
+       { OV7670_R3A_TSLB, 0x04 },              /* OV */
+       { OV7670_R12_COM7, OV7670_COM7_FMT_VGA }, /* VGA */
+       { OV7670_R11_CLKRC, 0x01 },
 /*
  * Set the hardware window.  These values from OV don't entirely
  * make sense - hstop is less than hstart.  But they work...
  */
-       { OV7670_REG_HSTART, 0x13 },
-       { OV7670_REG_HSTOP, 0x01 },
-       { OV7670_REG_HREF, 0xb6 },
-       { OV7670_REG_VSTART, 0x02 },
-       { OV7670_REG_VSTOP, 0x7a },
-       { OV7670_REG_VREF, 0x0a },
-
-       { OV7670_REG_COM3, 0x00 },
-       { OV7670_REG_COM14, 0x00 },
+       { OV7670_R17_HSTART, 0x13 },
+       { OV7670_R18_HSTOP, 0x01 },
+       { OV7670_R32_HREF, 0xb6 },
+       { OV7670_R19_VSTART, 0x02 },
+       { OV7670_R1A_VSTOP, 0x7a },
+       { OV7670_R03_VREF, 0x0a },
+
+       { OV7670_R0C_COM3, 0x00 },
+       { OV7670_R3E_COM14, 0x00 },
 /* Mystery scaling numbers */
        { 0x70, 0x3a },
        { 0x71, 0x35 },
        { 0x72, 0x11 },
        { 0x73, 0xf0 },
        { 0xa2, 0x02 },
-/*     { OV7670_REG_COM10, 0x0 }, */
+/*     { OV7670_R15_COM10, 0x0 }, */
 
 /* Gamma curve values */
        { 0x7a, 0x20 },
@@ -1580,37 +1625,37 @@ static const struct ov_i2c_regvals norm_7670[] = {
 
 /* AGC and AEC parameters.  Note we start by disabling those features,
    then turn them only after tweaking the values. */
-       { OV7670_REG_COM8, OV7670_COM8_FASTAEC
+       { OV7670_R13_COM8, OV7670_COM8_FASTAEC
                         | OV7670_COM8_AECSTEP
                         | OV7670_COM8_BFILT },
-       { OV7670_REG_GAIN, 0x00 },
-       { OV7670_REG_AECH, 0x00 },
-       { OV7670_REG_COM4, 0x40 }, /* magic reserved bit */
-       { OV7670_REG_COM9, 0x18 }, /* 4x gain + magic rsvd bit */
-       { OV7670_REG_BD50MAX, 0x05 },
-       { OV7670_REG_BD60MAX, 0x07 },
-       { OV7670_REG_AEW, 0x95 },
-       { OV7670_REG_AEB, 0x33 },
-       { OV7670_REG_VPT, 0xe3 },
-       { OV7670_REG_HAECC1, 0x78 },
-       { OV7670_REG_HAECC2, 0x68 },
+       { OV7670_R00_GAIN, 0x00 },
+       { OV7670_R10_AECH, 0x00 },
+       { OV7670_R0D_COM4, 0x40 }, /* magic reserved bit */
+       { OV7670_R14_COM9, 0x18 }, /* 4x gain + magic rsvd bit */
+       { OV7670_RA5_BD50MAX, 0x05 },
+       { OV7670_RAB_BD60MAX, 0x07 },
+       { OV7670_R24_AEW, 0x95 },
+       { OV7670_R25_AEB, 0x33 },
+       { OV7670_R26_VPT, 0xe3 },
+       { OV7670_R9F_HAECC1, 0x78 },
+       { OV7670_RA0_HAECC2, 0x68 },
        { 0xa1, 0x03 }, /* magic */
-       { OV7670_REG_HAECC3, 0xd8 },
-       { OV7670_REG_HAECC4, 0xd8 },
-       { OV7670_REG_HAECC5, 0xf0 },
-       { OV7670_REG_HAECC6, 0x90 },
-       { OV7670_REG_HAECC7, 0x94 },
-       { OV7670_REG_COM8, OV7670_COM8_FASTAEC
+       { OV7670_RA6_HAECC3, 0xd8 },
+       { OV7670_RA7_HAECC4, 0xd8 },
+       { OV7670_RA8_HAECC5, 0xf0 },
+       { OV7670_RA9_HAECC6, 0x90 },
+       { OV7670_RAA_HAECC7, 0x94 },
+       { OV7670_R13_COM8, OV7670_COM8_FASTAEC
                        | OV7670_COM8_AECSTEP
                        | OV7670_COM8_BFILT
                        | OV7670_COM8_AGC
                        | OV7670_COM8_AEC },
 
 /* Almost all of these are magic "reserved" values.  */
-       { OV7670_REG_COM5, 0x61 },
-       { OV7670_REG_COM6, 0x4b },
+       { OV7670_R0E_COM5, 0x61 },
+       { OV7670_R0F_COM6, 0x4b },
        { 0x16, 0x02 },
-       { OV7670_REG_MVFP, 0x07 },
+       { OV7670_R1E_MVFP, 0x07 },
        { 0x21, 0x02 },
        { 0x22, 0x91 },
        { 0x29, 0x07 },
@@ -1619,10 +1664,10 @@ static const struct ov_i2c_regvals norm_7670[] = {
        { 0x37, 0x1d },
        { 0x38, 0x71 },
        { 0x39, 0x2a },
-       { OV7670_REG_COM12, 0x78 },
+       { OV7670_R3C_COM12, 0x78 },
        { 0x4d, 0x40 },
        { 0x4e, 0x20 },
-       { OV7670_REG_GFIX, 0x00 },
+       { OV7670_R69_GFIX, 0x00 },
        { 0x6b, 0x4a },
        { 0x74, 0x10 },
        { 0x8d, 0x4f },
@@ -1657,9 +1702,9 @@ static const struct ov_i2c_regvals norm_7670[] = {
        { 0x6f, 0x9f },
                                        /* "9e for advance AWB" */
        { 0x6a, 0x40 },
-       { OV7670_REG_BLUE, 0x40 },
-       { OV7670_REG_RED, 0x60 },
-       { OV7670_REG_COM8, OV7670_COM8_FASTAEC
+       { OV7670_R01_BLUE, 0x40 },
+       { OV7670_R02_RED, 0x60 },
+       { OV7670_R13_COM8, OV7670_COM8_FASTAEC
                        | OV7670_COM8_AECSTEP
                        | OV7670_COM8_BFILT
                        | OV7670_COM8_AGC
@@ -1675,22 +1720,22 @@ static const struct ov_i2c_regvals norm_7670[] = {
        { 0x54, 0x80 },
        { 0x58, 0x9e },
 
-       { OV7670_REG_COM16, OV7670_COM16_AWBGAIN },
-       { OV7670_REG_EDGE, 0x00 },
+       { OV7670_R41_COM16, OV7670_COM16_AWBGAIN },
+       { OV7670_R3F_EDGE, 0x00 },
        { 0x75, 0x05 },
        { 0x76, 0xe1 },
        { 0x4c, 0x00 },
        { 0x77, 0x01 },
-       { OV7670_REG_COM13, OV7670_COM13_GAMMA
+       { OV7670_R3D_COM13, OV7670_COM13_GAMMA
                          | OV7670_COM13_UVSAT
                          | 2},         /* was 3 */
        { 0x4b, 0x09 },
        { 0xc9, 0x60 },
-       { OV7670_REG_COM16, 0x38 },
+       { OV7670_R41_COM16, 0x38 },
        { 0x56, 0x40 },
 
        { 0x34, 0x11 },
-       { OV7670_REG_COM11, OV7670_COM11_EXP|OV7670_COM11_HZAUTO },
+       { OV7670_R3B_COM11, OV7670_COM11_EXP|OV7670_COM11_HZAUTO },
        { 0xa4, 0x88 },
        { 0x96, 0x00 },
        { 0x97, 0x30 },
@@ -1825,10 +1870,13 @@ static unsigned char ov7670_abs_to_sm(unsigned char v)
 }
 
 /* Write a OV519 register */
-static int reg_w(struct sd *sd, __u16 index, __u16 value)
+static void reg_w(struct sd *sd, u16 index, u16 value)
 {
        int ret, req = 0;
 
+       if (sd->gspca_dev.usb_err < 0)
+               return;
+
        switch (sd->bridge) {
        case BRIDGE_OV511:
        case BRIDGE_OV511PLUS:
@@ -1838,6 +1886,8 @@ static int reg_w(struct sd *sd, __u16 index, __u16 value)
                req = 0x0a;
                /* fall through */
        case BRIDGE_W9968CF:
+               PDEBUG(D_USBO, "SET %02x %04x %04x",
+                               req, value, index);
                ret = usb_control_msg(sd->gspca_dev.dev,
                        usb_sndctrlpipe(sd->gspca_dev.dev, 0),
                        req,
@@ -1848,6 +1898,8 @@ static int reg_w(struct sd *sd, __u16 index, __u16 value)
                req = 1;
        }
 
+       PDEBUG(D_USBO, "SET %02x 0000 %04x %02x",
+                       req, index, value);
        sd->gspca_dev.usb_buf[0] = value;
        ret = usb_control_msg(sd->gspca_dev.dev,
                        usb_sndctrlpipe(sd->gspca_dev.dev, 0),
@@ -1857,22 +1909,22 @@ static int reg_w(struct sd *sd, __u16 index, __u16 value)
                        sd->gspca_dev.usb_buf, 1, 500);
 leave:
        if (ret < 0) {
-               err("Write reg 0x%04x -> [0x%02x] failed",
-                      value, index);
-               return ret;
+               err("reg_w %02x failed %d", index, ret);
+               sd->gspca_dev.usb_err = ret;
+               return;
        }
-
-       PDEBUG(D_USBO, "Write reg 0x%04x -> [0x%02x]", value, index);
-       return 0;
 }
 
 /* Read from a OV519 register, note not valid for the w9968cf!! */
 /* returns: negative is error, pos or zero is data */
-static int reg_r(struct sd *sd, __u16 index)
+static int reg_r(struct sd *sd, u16 index)
 {
        int ret;
        int req;
 
+       if (sd->gspca_dev.usb_err < 0)
+               return -1;
+
        switch (sd->bridge) {
        case BRIDGE_OV511:
        case BRIDGE_OV511PLUS:
@@ -1893,29 +1945,37 @@ static int reg_r(struct sd *sd, __u16 index)
 
        if (ret >= 0) {
                ret = sd->gspca_dev.usb_buf[0];
-               PDEBUG(D_USBI, "Read reg [0x%02X] -> 0x%04X", index, ret);
-       } else
-               err("Read reg [0x%02x] failed", index);
+               PDEBUG(D_USBI, "GET %02x 0000 %04x %02x",
+                       req, index, ret);
+       } else {
+               err("reg_r %02x failed %d", index, ret);
+               sd->gspca_dev.usb_err = ret;
+       }
 
        return ret;
 }
 
 /* Read 8 values from a OV519 register */
 static int reg_r8(struct sd *sd,
-                 __u16 index)
+                 u16 index)
 {
        int ret;
 
+       if (sd->gspca_dev.usb_err < 0)
+               return -1;
+
        ret = usb_control_msg(sd->gspca_dev.dev,
                        usb_rcvctrlpipe(sd->gspca_dev.dev, 0),
                        1,                      /* REQ_IO */
                        USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
                        0, index, sd->gspca_dev.usb_buf, 8, 500);
 
-       if (ret >= 0)
+       if (ret >= 0) {
                ret = sd->gspca_dev.usb_buf[0];
-       else
-               err("Read reg 8 [0x%02x] failed", index);
+       } else {
+               err("reg_r8 %02x failed %d", index, ret);
+               sd->gspca_dev.usb_err = ret;
+       }
 
        return ret;
 }
@@ -1926,34 +1986,37 @@ static int reg_r8(struct sd *sd,
  * that are in the same position as 0's in "mask" are preserved, regardless
  * of their respective state in "value".
  */
-static int reg_w_mask(struct sd *sd,
-                       __u16 index,
-                       __u8 value,
-                       __u8 mask)
+static void reg_w_mask(struct sd *sd,
+                       u16 index,
+                       u8 value,
+                       u8 mask)
 {
        int ret;
-       __u8 oldval;
+       u8 oldval;
 
        if (mask != 0xff) {
                value &= mask;                  /* Enforce mask on value */
                ret = reg_r(sd, index);
                if (ret < 0)
-                       return ret;
+                       return;
 
                oldval = ret & ~mask;           /* Clear the masked bits */
                value |= oldval;                /* Set the desired bits */
        }
-       return reg_w(sd, index, value);
+       reg_w(sd, index, value);
 }
 
 /*
  * Writes multiple (n) byte value to a single register. Only valid with certain
  * registers (0x30 and 0xc4 - 0xce).
  */
-static int ov518_reg_w32(struct sd *sd, __u16 index, u32 value, int n)
+static void ov518_reg_w32(struct sd *sd, u16 index, u32 value, int n)
 {
        int ret;
 
+       if (sd->gspca_dev.usb_err < 0)
+               return;
+
        *((__le32 *) sd->gspca_dev.usb_buf) = __cpu_to_le32(value);
 
        ret = usb_control_msg(sd->gspca_dev.dev,
@@ -1963,69 +2026,55 @@ static int ov518_reg_w32(struct sd *sd, __u16 index, u32 value, int n)
                        0, index,
                        sd->gspca_dev.usb_buf, n, 500);
        if (ret < 0) {
-               err("Write reg32 [%02x] %08x failed", index, value);
-               return ret;
+               err("reg_w32 %02x failed %d", index, ret);
+               sd->gspca_dev.usb_err = ret;
        }
-
-       return 0;
 }
 
-static int ov511_i2c_w(struct sd *sd, __u8 reg, __u8 value)
+static void ov511_i2c_w(struct sd *sd, u8 reg, u8 value)
 {
        int rc, retries;
 
-       PDEBUG(D_USBO, "i2c 0x%02x -> [0x%02x]", value, reg);
+       PDEBUG(D_USBO, "ov511_i2c_w %02x %02x", reg, value);
 
        /* Three byte write cycle */
        for (retries = 6; ; ) {
                /* Select camera register */
-               rc = reg_w(sd, R51x_I2C_SADDR_3, reg);
-               if (rc < 0)
-                       return rc;
+               reg_w(sd, R51x_I2C_SADDR_3, reg);
 
                /* Write "value" to I2C data port of OV511 */
-               rc = reg_w(sd, R51x_I2C_DATA, value);
-               if (rc < 0)
-                       return rc;
+               reg_w(sd, R51x_I2C_DATA, value);
 
                /* Initiate 3-byte write cycle */
-               rc = reg_w(sd, R511_I2C_CTL, 0x01);
-               if (rc < 0)
-                       return rc;
+               reg_w(sd, R511_I2C_CTL, 0x01);
 
                do {
                        rc = reg_r(sd, R511_I2C_CTL);
                } while (rc > 0 && ((rc & 1) == 0)); /* Retry until idle */
 
                if (rc < 0)
-                       return rc;
+                       return;
 
                if ((rc & 2) == 0) /* Ack? */
                        break;
                if (--retries < 0) {
                        PDEBUG(D_USBO, "i2c write retries exhausted");
-                       return -1;
+                       return;
                }
        }
-
-       return 0;
 }
 
-static int ov511_i2c_r(struct sd *sd, __u8 reg)
+static int ov511_i2c_r(struct sd *sd, u8 reg)
 {
        int rc, value, retries;
 
        /* Two byte write cycle */
        for (retries = 6; ; ) {
                /* Select camera register */
-               rc = reg_w(sd, R51x_I2C_SADDR_2, reg);
-               if (rc < 0)
-                       return rc;
+               reg_w(sd, R51x_I2C_SADDR_2, reg);
 
                /* Initiate 2-byte write cycle */
-               rc = reg_w(sd, R511_I2C_CTL, 0x03);
-               if (rc < 0)
-                       return rc;
+               reg_w(sd, R511_I2C_CTL, 0x03);
 
                do {
                        rc = reg_r(sd, R511_I2C_CTL);
@@ -2049,9 +2098,7 @@ static int ov511_i2c_r(struct sd *sd, __u8 reg)
        /* Two byte read cycle */
        for (retries = 6; ; ) {
                /* Initiate 2-byte read cycle */
-               rc = reg_w(sd, R511_I2C_CTL, 0x05);
-               if (rc < 0)
-                       return rc;
+               reg_w(sd, R511_I2C_CTL, 0x05);
 
                do {
                        rc = reg_r(sd, R511_I2C_CTL);
@@ -2064,9 +2111,7 @@ static int ov511_i2c_r(struct sd *sd, __u8 reg)
                        break;
 
                /* I2C abort */
-               rc = reg_w(sd, R511_I2C_CTL, 0x10);
-               if (rc < 0)
-                       return rc;
+               reg_w(sd, R511_I2C_CTL, 0x10);
 
                if (--retries < 0) {
                        PDEBUG(D_USBI, "i2c read retries exhausted");
@@ -2076,12 +2121,10 @@ static int ov511_i2c_r(struct sd *sd, __u8 reg)
 
        value = reg_r(sd, R51x_I2C_DATA);
 
-       PDEBUG(D_USBI, "i2c [0x%02X] -> 0x%02X", reg, value);
+       PDEBUG(D_USBI, "ov511_i2c_r %02x %02x", reg, value);
 
        /* This is needed to make i2c_w() work */
-       rc = reg_w(sd, R511_I2C_CTL, 0x05);
-       if (rc < 0)
-               return rc;
+       reg_w(sd, R511_I2C_CTL, 0x05);
 
        return value;
 }
@@ -2091,32 +2134,24 @@ static int ov511_i2c_r(struct sd *sd, __u8 reg)
  * This is normally only called from i2c_w(). Note that this function
  * always succeeds regardless of whether the sensor is present and working.
  */
-static int ov518_i2c_w(struct sd *sd,
-               __u8 reg,
-               __u8 value)
+static void ov518_i2c_w(struct sd *sd,
+               u8 reg,
+               u8 value)
 {
-       int rc;
-
-       PDEBUG(D_USBO, "i2c 0x%02x -> [0x%02x]", value, reg);
+       PDEBUG(D_USBO, "ov518_i2c_w %02x %02x", reg, value);
 
        /* Select camera register */
-       rc = reg_w(sd, R51x_I2C_SADDR_3, reg);
-       if (rc < 0)
-               return rc;
+       reg_w(sd, R51x_I2C_SADDR_3, reg);
 
        /* Write "value" to I2C data port of OV511 */
-       rc = reg_w(sd, R51x_I2C_DATA, value);
-       if (rc < 0)
-               return rc;
+       reg_w(sd, R51x_I2C_DATA, value);
 
        /* Initiate 3-byte write cycle */
-       rc = reg_w(sd, R518_I2C_CTL, 0x01);
-       if (rc < 0)
-               return rc;
+       reg_w(sd, R518_I2C_CTL, 0x01);
 
        /* wait for write complete */
        msleep(4);
-       return reg_r8(sd, R518_I2C_CTL);
+       reg_r8(sd, R518_I2C_CTL);
 }
 
 /*
@@ -2126,105 +2161,102 @@ static int ov518_i2c_w(struct sd *sd,
  * This is normally only called from i2c_r(). Note that this function
  * always succeeds regardless of whether the sensor is present and working.
  */
-static int ov518_i2c_r(struct sd *sd, __u8 reg)
+static int ov518_i2c_r(struct sd *sd, u8 reg)
 {
-       int rc, value;
+       int value;
 
        /* Select camera register */
-       rc = reg_w(sd, R51x_I2C_SADDR_2, reg);
-       if (rc < 0)
-               return rc;
+       reg_w(sd, R51x_I2C_SADDR_2, reg);
 
        /* Initiate 2-byte write cycle */
-       rc = reg_w(sd, R518_I2C_CTL, 0x03);
-       if (rc < 0)
-               return rc;
+       reg_w(sd, R518_I2C_CTL, 0x03);
 
        /* Initiate 2-byte read cycle */
-       rc = reg_w(sd, R518_I2C_CTL, 0x05);
-       if (rc < 0)
-               return rc;
+       reg_w(sd, R518_I2C_CTL, 0x05);
        value = reg_r(sd, R51x_I2C_DATA);
-       PDEBUG(D_USBI, "i2c [0x%02X] -> 0x%02X", reg, value);
+       PDEBUG(D_USBI, "ov518_i2c_r %02x %02x", reg, value);
        return value;
 }
 
-static int ovfx2_i2c_w(struct sd *sd, __u8 reg, __u8 value)
+static void ovfx2_i2c_w(struct sd *sd, u8 reg, u8 value)
 {
        int ret;
 
+       if (sd->gspca_dev.usb_err < 0)
+               return;
+
        ret = usb_control_msg(sd->gspca_dev.dev,
                        usb_sndctrlpipe(sd->gspca_dev.dev, 0),
                        0x02,
                        USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
-                       (__u16)value, (__u16)reg, NULL, 0, 500);
+                       (u16) value, (u16) reg, NULL, 0, 500);
 
        if (ret < 0) {
-               err("i2c 0x%02x -> [0x%02x] failed", value, reg);
-               return ret;
+               err("ovfx2_i2c_w %02x failed %d", reg, ret);
+               sd->gspca_dev.usb_err = ret;
        }
 
-       PDEBUG(D_USBO, "i2c 0x%02x -> [0x%02x]", value, reg);
-       return 0;
+       PDEBUG(D_USBO, "ovfx2_i2c_w %02x %02x", reg, value);
 }
 
-static int ovfx2_i2c_r(struct sd *sd, __u8 reg)
+static int ovfx2_i2c_r(struct sd *sd, u8 reg)
 {
        int ret;
 
+       if (sd->gspca_dev.usb_err < 0)
+               return -1;
+
        ret = usb_control_msg(sd->gspca_dev.dev,
                        usb_rcvctrlpipe(sd->gspca_dev.dev, 0),
                        0x03,
                        USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
-                       0, (__u16)reg, sd->gspca_dev.usb_buf, 1, 500);
+                       0, (u16) reg, sd->gspca_dev.usb_buf, 1, 500);
 
        if (ret >= 0) {
                ret = sd->gspca_dev.usb_buf[0];
-               PDEBUG(D_USBI, "i2c [0x%02X] -> 0x%02X", reg, ret);
-       } else
-               err("i2c read [0x%02x] failed", reg);
+               PDEBUG(D_USBI, "ovfx2_i2c_r %02x %02x", reg, ret);
+       } else {
+               err("ovfx2_i2c_r %02x failed %d", reg, ret);
+               sd->gspca_dev.usb_err = ret;
+       }
 
        return ret;
 }
 
-static int i2c_w(struct sd *sd, __u8 reg, __u8 value)
+static void i2c_w(struct sd *sd, u8 reg, u8 value)
 {
-       int ret = -1;
-
        if (sd->sensor_reg_cache[reg] == value)
-               return 0;
+               return;
 
        switch (sd->bridge) {
        case BRIDGE_OV511:
        case BRIDGE_OV511PLUS:
-               ret = ov511_i2c_w(sd, reg, value);
+               ov511_i2c_w(sd, reg, value);
                break;
        case BRIDGE_OV518:
        case BRIDGE_OV518PLUS:
        case BRIDGE_OV519:
-               ret = ov518_i2c_w(sd, reg, value);
+               ov518_i2c_w(sd, reg, value);
                break;
        case BRIDGE_OVFX2:
-               ret = ovfx2_i2c_w(sd, reg, value);
+               ovfx2_i2c_w(sd, reg, value);
                break;
        case BRIDGE_W9968CF:
-               ret = w9968cf_i2c_w(sd, reg, value);
+               w9968cf_i2c_w(sd, reg, value);
                break;
        }
 
-       if (ret >= 0) {
+       if (sd->gspca_dev.usb_err >= 0) {
                /* Up on sensor reset empty the register cache */
                if (reg == 0x12 && (value & 0x80))
                        memset(sd->sensor_reg_cache, -1,
-                              sizeof(sd->sensor_reg_cache));
+                               sizeof(sd->sensor_reg_cache));
                else
                        sd->sensor_reg_cache[reg] = value;
        }
-
-       return ret;
 }
 
-static int i2c_r(struct sd *sd, __u8 reg)
+static int i2c_r(struct sd *sd, u8 reg)
 {
        int ret = -1;
 
@@ -2260,95 +2292,99 @@ static int i2c_r(struct sd *sd, __u8 reg)
  * that are in the same position as 0's in "mask" are preserved, regardless
  * of their respective state in "value".
  */
-static int i2c_w_mask(struct sd *sd,
-                  __u8 reg,
-                  __u8 value,
-                  __u8 mask)
+static void i2c_w_mask(struct sd *sd,
+                       u8 reg,
+                       u8 value,
+                       u8 mask)
 {
        int rc;
-       __u8 oldval;
+       u8 oldval;
 
        value &= mask;                  /* Enforce mask on value */
        rc = i2c_r(sd, reg);
        if (rc < 0)
-               return rc;
+               return;
        oldval = rc & ~mask;            /* Clear the masked bits */
        value |= oldval;                /* Set the desired bits */
-       return i2c_w(sd, reg, value);
+       i2c_w(sd, reg, value);
 }
 
 /* Temporarily stops OV511 from functioning. Must do this before changing
  * registers while the camera is streaming */
-static inline int ov51x_stop(struct sd *sd)
+static inline void ov51x_stop(struct sd *sd)
 {
        PDEBUG(D_STREAM, "stopping");
        sd->stopped = 1;
        switch (sd->bridge) {
        case BRIDGE_OV511:
        case BRIDGE_OV511PLUS:
-               return reg_w(sd, R51x_SYS_RESET, 0x3d);
+               reg_w(sd, R51x_SYS_RESET, 0x3d);
+               break;
        case BRIDGE_OV518:
        case BRIDGE_OV518PLUS:
-               return reg_w_mask(sd, R51x_SYS_RESET, 0x3a, 0x3a);
+               reg_w_mask(sd, R51x_SYS_RESET, 0x3a, 0x3a);
+               break;
        case BRIDGE_OV519:
-               return reg_w(sd, OV519_SYS_RESET1, 0x0f);
+               reg_w(sd, OV519_R51_RESET1, 0x0f);
+               reg_w(sd, OV519_R51_RESET1, 0x00);
+               reg_w(sd, 0x22, 0x00);          /* FRAR */
+               break;
        case BRIDGE_OVFX2:
-               return reg_w_mask(sd, 0x0f, 0x00, 0x02);
+               reg_w_mask(sd, 0x0f, 0x00, 0x02);
+               break;
        case BRIDGE_W9968CF:
-               return reg_w(sd, 0x3c, 0x0a05); /* stop USB transfer */
+               reg_w(sd, 0x3c, 0x0a05); /* stop USB transfer */
+               break;
        }
-
-       return 0;
 }
 
 /* Restarts OV511 after ov511_stop() is called. Has no effect if it is not
  * actually stopped (for performance). */
-static inline int ov51x_restart(struct sd *sd)
+static inline void ov51x_restart(struct sd *sd)
 {
-       int rc;
-
        PDEBUG(D_STREAM, "restarting");
        if (!sd->stopped)
-               return 0;
+               return;
        sd->stopped = 0;
 
        /* Reinitialize the stream */
        switch (sd->bridge) {
        case BRIDGE_OV511:
        case BRIDGE_OV511PLUS:
-               return reg_w(sd, R51x_SYS_RESET, 0x00);
+               reg_w(sd, R51x_SYS_RESET, 0x00);
+               break;
        case BRIDGE_OV518:
        case BRIDGE_OV518PLUS:
-               rc = reg_w(sd, 0x2f, 0x80);
-               if (rc < 0)
-                       return rc;
-               return reg_w(sd, R51x_SYS_RESET, 0x00);
+               reg_w(sd, 0x2f, 0x80);
+               reg_w(sd, R51x_SYS_RESET, 0x00);
+               break;
        case BRIDGE_OV519:
-               return reg_w(sd, OV519_SYS_RESET1, 0x00);
+               reg_w(sd, OV519_R51_RESET1, 0x0f);
+               reg_w(sd, OV519_R51_RESET1, 0x00);
+               reg_w(sd, 0x22, 0x1d);          /* FRAR */
+               break;
        case BRIDGE_OVFX2:
-               return reg_w_mask(sd, 0x0f, 0x02, 0x02);
+               reg_w_mask(sd, 0x0f, 0x02, 0x02);
+               break;
        case BRIDGE_W9968CF:
-               return reg_w(sd, 0x3c, 0x8a05); /* USB FIFO enable */
+               reg_w(sd, 0x3c, 0x8a05); /* USB FIFO enable */
+               break;
        }
-
-       return 0;
 }
 
-static int ov51x_set_slave_ids(struct sd *sd, __u8 slave);
+static void ov51x_set_slave_ids(struct sd *sd, u8 slave);
 
 /* This does an initial reset of an OmniVision sensor and ensures that I2C
  * is synchronized. Returns <0 on failure.
  */
-static int init_ov_sensor(struct sd *sd, __u8 slave)
+static int init_ov_sensor(struct sd *sd, u8 slave)
 {
        int i;
 
-       if (ov51x_set_slave_ids(sd, slave) < 0)
-               return -EIO;
+       ov51x_set_slave_ids(sd, slave);
 
        /* Reset the sensor */
-       if (i2c_w(sd, 0x12, 0x80) < 0)
-               return -EIO;
+       i2c_w(sd, 0x12, 0x80);
 
        /* Wait for it to initialize */
        msleep(150);
@@ -2361,15 +2397,16 @@ static int init_ov_sensor(struct sd *sd, __u8 slave)
                }
 
                /* Reset the sensor */
-               if (i2c_w(sd, 0x12, 0x80) < 0)
-                       return -EIO;
+               i2c_w(sd, 0x12, 0x80);
+
                /* Wait for it to initialize */
                msleep(150);
+
                /* Dummy read to sync I2C */
                if (i2c_r(sd, 0x00) < 0)
-                       return -EIO;
+                       return -1;
        }
-       return -EIO;
+       return -1;
 }
 
 /* Set the read and write slave IDs. The "slave" argument is the write slave,
@@ -2377,53 +2414,40 @@ static int init_ov_sensor(struct sd *sd, __u8 slave)
  * This should not be called from outside the i2c I/O functions.
  * Sets I2C read and write slave IDs. Returns <0 for error
  */
-static int ov51x_set_slave_ids(struct sd *sd,
-                               __u8 slave)
+static void ov51x_set_slave_ids(struct sd *sd,
+                               u8 slave)
 {
-       int rc;
-
        switch (sd->bridge) {
        case BRIDGE_OVFX2:
-               return reg_w(sd, OVFX2_I2C_ADDR, slave);
+               reg_w(sd, OVFX2_I2C_ADDR, slave);
+               return;
        case BRIDGE_W9968CF:
                sd->sensor_addr = slave;
-               return 0;
+               return;
        }
 
-       rc = reg_w(sd, R51x_I2C_W_SID, slave);
-       if (rc < 0)
-               return rc;
-       return reg_w(sd, R51x_I2C_R_SID, slave + 1);
+       reg_w(sd, R51x_I2C_W_SID, slave);
+       reg_w(sd, R51x_I2C_R_SID, slave + 1);
 }
 
-static int write_regvals(struct sd *sd,
+static void write_regvals(struct sd *sd,
                         const struct ov_regvals *regvals,
                         int n)
 {
-       int rc;
-
        while (--n >= 0) {
-               rc = reg_w(sd, regvals->reg, regvals->val);
-               if (rc < 0)
-                       return rc;
+               reg_w(sd, regvals->reg, regvals->val);
                regvals++;
        }
-       return 0;
 }
 
-static int write_i2c_regvals(struct sd *sd,
-                            const struct ov_i2c_regvals *regvals,
-                            int n)
+static void write_i2c_regvals(struct sd *sd,
+                       const struct ov_i2c_regvals *regvals,
+                       int n)
 {
-       int rc;
-
        while (--n >= 0) {
-               rc = i2c_w(sd, regvals->reg, regvals->val);
-               if (rc < 0)
-                       return rc;
+               i2c_w(sd, regvals->reg, regvals->val);
                regvals++;
        }
-       return 0;
 }
 
 /****************************************************************************
@@ -2433,13 +2457,13 @@ static int write_i2c_regvals(struct sd *sd,
  ***************************************************************************/
 
 /* This initializes the OV2x10 / OV3610 / OV3620 */
-static int ov_hires_configure(struct sd *sd)
+static void ov_hires_configure(struct sd *sd)
 {
        int high, low;
 
        if (sd->bridge != BRIDGE_OVFX2) {
                err("error hires sensors only supported with ovfx2");
-               return -1;
+               return;
        }
 
        PDEBUG(D_PROBE, "starting ov hires configuration");
@@ -2455,20 +2479,15 @@ static int ov_hires_configure(struct sd *sd)
                PDEBUG(D_PROBE, "Sensor is an OV3610");
                sd->sensor = SEN_OV3610;
        } else {
-               err("Error unknown sensor type: 0x%02x%02x",
-                      high, low);
-               return -1;
+               err("Error unknown sensor type: %02x%02x",
+                       high, low);
        }
-
-       /* Set sensor-specific vars */
-       return 0;
 }
 
-
 /* This initializes the OV8110, OV8610 sensor. The OV8110 uses
  * the same register settings as the OV8610, since they are very similar.
  */
-static int ov8xx0_configure(struct sd *sd)
+static void ov8xx0_configure(struct sd *sd)
 {
        int rc;
 
@@ -2478,27 +2497,21 @@ static int ov8xx0_configure(struct sd *sd)
        rc = i2c_r(sd, OV7610_REG_COM_I);
        if (rc < 0) {
                PDEBUG(D_ERR, "Error detecting sensor type");
-               return -1;
+               return;
        }
-       if ((rc & 3) == 1) {
+       if ((rc & 3) == 1)
                sd->sensor = SEN_OV8610;
-       } else {
+       else
                err("Unknown image sensor version: %d", rc & 3);
-               return -1;
-       }
-
-       /* Set sensor-specific vars */
-       return 0;
 }
 
 /* This initializes the OV7610, OV7620, or OV76BE sensor. The OV76BE uses
  * the same register settings as the OV7610, since they are very similar.
  */
-static int ov7xx0_configure(struct sd *sd)
+static void ov7xx0_configure(struct sd *sd)
 {
        int rc, high, low;
 
-
        PDEBUG(D_PROBE, "starting OV7xx0 configuration");
 
        /* Detect sensor (sub)type */
@@ -2508,7 +2521,7 @@ static int ov7xx0_configure(struct sd *sd)
         * it appears to be wrongly detected as a 7610 by default */
        if (rc < 0) {
                PDEBUG(D_ERR, "Error detecting sensor type");
-               return -1;
+               return;
        }
        if ((rc & 3) == 3) {
                /* quick hack to make OV7670s work */
@@ -2536,19 +2549,19 @@ static int ov7xx0_configure(struct sd *sd)
                high = i2c_r(sd, 0x0a);
                if (high < 0) {
                        PDEBUG(D_ERR, "Error detecting camera chip PID");
-                       return high;
+                       return;
                }
                low = i2c_r(sd, 0x0b);
                if (low < 0) {
                        PDEBUG(D_ERR, "Error detecting camera chip VER");
-                       return low;
+                       return;
                }
                if (high == 0x76) {
                        switch (low) {
                        case 0x30:
                                err("Sensor is an OV7630/OV7635");
                                err("7630 is not supported by this driver");
-                               return -1;
+                               return;
                        case 0x40:
                                PDEBUG(D_PROBE, "Sensor is an OV7645");
                                sd->sensor = SEN_OV7640; /* FIXME */
@@ -2563,7 +2576,7 @@ static int ov7xx0_configure(struct sd *sd)
                                break;
                        default:
                                PDEBUG(D_PROBE, "Unknown sensor: 0x76%x", low);
-                               return -1;
+                               return;
                        }
                } else {
                        PDEBUG(D_PROBE, "Sensor is an OV7620");
@@ -2571,15 +2584,11 @@ static int ov7xx0_configure(struct sd *sd)
                }
        } else {
                err("Unknown image sensor version: %d", rc & 3);
-               return -1;
        }
-
-       /* Set sensor-specific vars */
-       return 0;
 }
 
 /* This initializes the OV6620, OV6630, OV6630AE, or OV6630AF sensor. */
-static int ov6xx0_configure(struct sd *sd)
+static void ov6xx0_configure(struct sd *sd)
 {
        int rc;
        PDEBUG(D_PROBE, "starting OV6xx0 configuration");
@@ -2588,7 +2597,7 @@ static int ov6xx0_configure(struct sd *sd)
        rc = i2c_r(sd, OV7610_REG_COM_I);
        if (rc < 0) {
                PDEBUG(D_ERR, "Error detecting sensor type");
-               return -1;
+               return;
        }
 
        /* Ugh. The first two bits are the version bits, but
@@ -2619,13 +2628,11 @@ static int ov6xx0_configure(struct sd *sd)
                break;
        default:
                err("FATAL: Unknown sensor version: 0x%02x", rc);
-               return -1;
+               return;
        }
 
        /* Set sensor-specific vars */
        sd->sif = 1;
-
-       return 0;
 }
 
 /* Turns on or off the LED. Only has an effect with OV511+/OV518(+)/OV519 */
@@ -2637,14 +2644,14 @@ static void ov51x_led_control(struct sd *sd, int on)
        switch (sd->bridge) {
        /* OV511 has no LED control */
        case BRIDGE_OV511PLUS:
-               reg_w(sd, R511_SYS_LED_CTL, on ? 1 : 0);
+               reg_w(sd, R511_SYS_LED_CTL, on);
                break;
        case BRIDGE_OV518:
        case BRIDGE_OV518PLUS:
-               reg_w_mask(sd, R518_GPIO_OUT, on ? 0x02 : 0x00, 0x02);
+               reg_w_mask(sd, R518_GPIO_OUT, 0x02 * on, 0x02);
                break;
        case BRIDGE_OV519:
-               reg_w_mask(sd, OV519_GPIO_DATA_OUT0, !on, 1);   /* 0 / 1 */
+               reg_w_mask(sd, OV519_GPIO_DATA_OUT0, on, 1);
                break;
        }
 }
@@ -2679,7 +2686,7 @@ static void sd_reset_snapshot(struct gspca_dev *gspca_dev)
        }
 }
 
-static int ov51x_upload_quan_tables(struct sd *sd)
+static void ov51x_upload_quan_tables(struct sd *sd)
 {
        const unsigned char yQuanTable511[] = {
                0, 1, 1, 2, 2, 3, 3, 4,
@@ -2710,7 +2717,6 @@ static int ov51x_upload_quan_tables(struct sd *sd)
                6, 6, 6, 6, 7, 7, 7, 8,
                7, 7, 6, 7, 7, 7, 8, 8
        };
-
        const unsigned char uvQuanTable518[] = {
                6, 6, 6, 7, 7, 7, 7, 7,
                6, 6, 6, 7, 7, 7, 7, 7,
@@ -2720,18 +2726,18 @@ static int ov51x_upload_quan_tables(struct sd *sd)
 
        const unsigned char *pYTable, *pUVTable;
        unsigned char val0, val1;
-       int i, size, rc, reg = R51x_COMP_LUT_BEGIN;
+       int i, size, reg = R51x_COMP_LUT_BEGIN;
 
        PDEBUG(D_PROBE, "Uploading quantization tables");
 
        if (sd->bridge == BRIDGE_OV511 || sd->bridge == BRIDGE_OV511PLUS) {
                pYTable = yQuanTable511;
                pUVTable = uvQuanTable511;
-               size  = 32;
+               size = 32;
        } else {
                pYTable = yQuanTable518;
                pUVTable = uvQuanTable518;
-               size  = 16;
+               size = 16;
        }
 
        for (i = 0; i < size; i++) {
@@ -2740,30 +2746,23 @@ static int ov51x_upload_quan_tables(struct sd *sd)
                val0 &= 0x0f;
                val1 &= 0x0f;
                val0 |= val1 << 4;
-               rc = reg_w(sd, reg, val0);
-               if (rc < 0)
-                       return rc;
+               reg_w(sd, reg, val0);
 
                val0 = *pUVTable++;
                val1 = *pUVTable++;
                val0 &= 0x0f;
                val1 &= 0x0f;
                val0 |= val1 << 4;
-               rc = reg_w(sd, reg + size, val0);
-               if (rc < 0)
-                       return rc;
+               reg_w(sd, reg + size, val0);
 
                reg++;
        }
-
-       return 0;
 }
 
 /* This initializes the OV511/OV511+ and the sensor */
-static int ov511_configure(struct gspca_dev *gspca_dev)
+static void ov511_configure(struct gspca_dev *gspca_dev)
 {
        struct sd *sd = (struct sd *) gspca_dev;
-       int rc;
 
        /* For 511 and 511+ */
        const struct ov_regvals init_511[] = {
@@ -2809,42 +2808,27 @@ static int ov511_configure(struct gspca_dev *gspca_dev)
 
        PDEBUG(D_PROBE, "Device custom id %x", reg_r(sd, R51x_SYS_CUST_ID));
 
-       rc = write_regvals(sd, init_511, ARRAY_SIZE(init_511));
-       if (rc < 0)
-               return rc;
+       write_regvals(sd, init_511, ARRAY_SIZE(init_511));
 
        switch (sd->bridge) {
        case BRIDGE_OV511:
-               rc = write_regvals(sd, norm_511, ARRAY_SIZE(norm_511));
-               if (rc < 0)
-                       return rc;
+               write_regvals(sd, norm_511, ARRAY_SIZE(norm_511));
                break;
        case BRIDGE_OV511PLUS:
-               rc = write_regvals(sd, norm_511_p, ARRAY_SIZE(norm_511_p));
-               if (rc < 0)
-                       return rc;
+               write_regvals(sd, norm_511_p, ARRAY_SIZE(norm_511_p));
                break;
        }
 
        /* Init compression */
-       rc = write_regvals(sd, compress_511, ARRAY_SIZE(compress_511));
-       if (rc < 0)
-               return rc;
-
-       rc = ov51x_upload_quan_tables(sd);
-       if (rc < 0) {
-               PDEBUG(D_ERR, "Error uploading quantization tables");
-               return rc;
-       }
+       write_regvals(sd, compress_511, ARRAY_SIZE(compress_511));
 
-       return 0;
+       ov51x_upload_quan_tables(sd);
 }
 
 /* This initializes the OV518/OV518+ and the sensor */
-static int ov518_configure(struct gspca_dev *gspca_dev)
+static void ov518_configure(struct gspca_dev *gspca_dev)
 {
        struct sd *sd = (struct sd *) gspca_dev;
-       int rc;
 
        /* For 518 and 518+ */
        const struct ov_regvals init_518[] = {
@@ -2892,65 +2876,49 @@ static int ov518_configure(struct gspca_dev *gspca_dev)
 
        /* First 5 bits of custom ID reg are a revision ID on OV518 */
        PDEBUG(D_PROBE, "Device revision %d",
-              0x1F & reg_r(sd, R51x_SYS_CUST_ID));
+               0x1f & reg_r(sd, R51x_SYS_CUST_ID));
 
-       rc = write_regvals(sd, init_518, ARRAY_SIZE(init_518));
-       if (rc < 0)
-               return rc;
+       write_regvals(sd, init_518, ARRAY_SIZE(init_518));
 
        /* Set LED GPIO pin to output mode */
-       rc = reg_w_mask(sd, R518_GPIO_CTL, 0x00, 0x02);
-       if (rc < 0)
-               return rc;
+       reg_w_mask(sd, R518_GPIO_CTL, 0x00, 0x02);
 
        switch (sd->bridge) {
        case BRIDGE_OV518:
-               rc = write_regvals(sd, norm_518, ARRAY_SIZE(norm_518));
-               if (rc < 0)
-                       return rc;
+               write_regvals(sd, norm_518, ARRAY_SIZE(norm_518));
                break;
        case BRIDGE_OV518PLUS:
-               rc = write_regvals(sd, norm_518_p, ARRAY_SIZE(norm_518_p));
-               if (rc < 0)
-                       return rc;
+               write_regvals(sd, norm_518_p, ARRAY_SIZE(norm_518_p));
                break;
        }
 
-       rc = ov51x_upload_quan_tables(sd);
-       if (rc < 0) {
-               PDEBUG(D_ERR, "Error uploading quantization tables");
-               return rc;
-       }
+       ov51x_upload_quan_tables(sd);
 
-       rc = reg_w(sd, 0x2f, 0x80);
-       if (rc < 0)
-               return rc;
-
-       return 0;
+       reg_w(sd, 0x2f, 0x80);
 }
 
-static int ov519_configure(struct sd *sd)
+static void ov519_configure(struct sd *sd)
 {
        static const struct ov_regvals init_519[] = {
-               { 0x5a,  0x6d }, /* EnableSystem */
-               { 0x53,  0x9b },
-               { 0x54,  0xff }, /* set bit2 to enable jpeg */
-               { 0x5d,  0x03 },
-               { 0x49,  0x01 },
-               { 0x48,  0x00 },
+               { 0x5a, 0x6d }, /* EnableSystem */
+               { 0x53, 0x9b },
+               { OV519_R54_EN_CLK1, 0xff }, /* set bit2 to enable jpeg */
+               { 0x5d, 0x03 },
+               { 0x49, 0x01 },
+               { 0x48, 0x00 },
                /* Set LED pin to output mode. Bit 4 must be cleared or sensor
                 * detection will fail. This deserves further investigation. */
                { OV519_GPIO_IO_CTRL0,   0xee },
-               { 0x51,  0x0f }, /* SetUsbInit */
-               { 0x51,  0x00 },
-               { 0x22,  0x00 },
+               { OV519_R51_RESET1, 0x0f },
+               { OV519_R51_RESET1, 0x00 },
+               { 0x22, 0x00 },
                /* windows reads 0x55 at this point*/
        };
 
-       return write_regvals(sd, init_519, ARRAY_SIZE(init_519));
+       write_regvals(sd, init_519, ARRAY_SIZE(init_519));
 }
 
-static int ovfx2_configure(struct sd *sd)
+static void ovfx2_configure(struct sd *sd)
 {
        static const struct ov_regvals init_fx2[] = {
                { 0x00, 0x60 },
@@ -2964,7 +2932,7 @@ static int ovfx2_configure(struct sd *sd)
 
        sd->stopped = 1;
 
-       return write_regvals(sd, init_fx2, ARRAY_SIZE(init_fx2));
+       write_regvals(sd, init_fx2, ARRAY_SIZE(init_fx2));
 }
 
 /* this function is called at probe time */
@@ -2973,99 +2941,119 @@ static int sd_config(struct gspca_dev *gspca_dev,
 {
        struct sd *sd = (struct sd *) gspca_dev;
        struct cam *cam = &gspca_dev->cam;
-       int ret = 0;
 
        sd->bridge = id->driver_info & BRIDGE_MASK;
-       sd->invert_led = id->driver_info & BRIDGE_INVERT_LED;
+       sd->invert_led = (id->driver_info & BRIDGE_INVERT_LED) != 0;
 
        switch (sd->bridge) {
        case BRIDGE_OV511:
        case BRIDGE_OV511PLUS:
-               ret = ov511_configure(gspca_dev);
+               cam->cam_mode = ov511_vga_mode;
+               cam->nmodes = ARRAY_SIZE(ov511_vga_mode);
                break;
        case BRIDGE_OV518:
        case BRIDGE_OV518PLUS:
-               ret = ov518_configure(gspca_dev);
+               cam->cam_mode = ov518_vga_mode;
+               cam->nmodes = ARRAY_SIZE(ov518_vga_mode);
                break;
        case BRIDGE_OV519:
-               ret = ov519_configure(sd);
+               cam->cam_mode = ov519_vga_mode;
+               cam->nmodes = ARRAY_SIZE(ov519_vga_mode);
+               sd->invert_led = !sd->invert_led;
                break;
        case BRIDGE_OVFX2:
-               ret = ovfx2_configure(sd);
+               cam->cam_mode = ov519_vga_mode;
+               cam->nmodes = ARRAY_SIZE(ov519_vga_mode);
                cam->bulk_size = OVFX2_BULK_SIZE;
                cam->bulk_nurbs = MAX_NURBS;
                cam->bulk = 1;
                break;
        case BRIDGE_W9968CF:
-               ret = w9968cf_configure(sd);
+               cam->cam_mode = w9968cf_vga_mode;
+               cam->nmodes = ARRAY_SIZE(w9968cf_vga_mode);
                cam->reverse_alts = 1;
                break;
        }
 
-       if (ret)
-               goto error;
+       gspca_dev->cam.ctrls = sd->ctrls;
+       sd->quality = QUALITY_DEF;
 
-       ov51x_led_control(sd, 0);       /* turn LED off */
+       return 0;
+}
+
+/* this function is called at probe and resume time */
+static int sd_init(struct gspca_dev *gspca_dev)
+{
+       struct sd *sd = (struct sd *) gspca_dev;
+       struct cam *cam = &gspca_dev->cam;
+
+       switch (sd->bridge) {
+       case BRIDGE_OV511:
+       case BRIDGE_OV511PLUS:
+               ov511_configure(gspca_dev);
+               break;
+       case BRIDGE_OV518:
+       case BRIDGE_OV518PLUS:
+               ov518_configure(gspca_dev);
+               break;
+       case BRIDGE_OV519:
+               ov519_configure(sd);
+               break;
+       case BRIDGE_OVFX2:
+               ovfx2_configure(sd);
+               break;
+       case BRIDGE_W9968CF:
+               w9968cf_configure(sd);
+               break;
+       }
 
        /* The OV519 must be more aggressive about sensor detection since
         * I2C write will never fail if the sensor is not present. We have
         * to try to initialize the sensor to detect its presence */
+       sd->sensor = -1;
 
        /* Test for 76xx */
        if (init_ov_sensor(sd, OV7xx0_SID) >= 0) {
-               if (ov7xx0_configure(sd) < 0) {
-                       PDEBUG(D_ERR, "Failed to configure OV7xx0");
-                       goto error;
-               }
+               ov7xx0_configure(sd);
+
        /* Test for 6xx0 */
        } else if (init_ov_sensor(sd, OV6xx0_SID) >= 0) {
-               if (ov6xx0_configure(sd) < 0) {
-                       PDEBUG(D_ERR, "Failed to configure OV6xx0");
-                       goto error;
-               }
+               ov6xx0_configure(sd);
+
        /* Test for 8xx0 */
        } else if (init_ov_sensor(sd, OV8xx0_SID) >= 0) {
-               if (ov8xx0_configure(sd) < 0) {
-                       PDEBUG(D_ERR, "Failed to configure OV8xx0");
-                       goto error;
-               }
+               ov8xx0_configure(sd);
+
        /* Test for 3xxx / 2xxx */
        } else if (init_ov_sensor(sd, OV_HIRES_SID) >= 0) {
-               if (ov_hires_configure(sd) < 0) {
-                       PDEBUG(D_ERR, "Failed to configure high res OV");
-                       goto error;
-               }
+               ov_hires_configure(sd);
        } else {
                err("Can't determine sensor slave IDs");
                goto error;
        }
 
+       if (sd->sensor < 0)
+               goto error;
+
+       ov51x_led_control(sd, 0);       /* turn LED off */
+
        switch (sd->bridge) {
        case BRIDGE_OV511:
        case BRIDGE_OV511PLUS:
-               if (!sd->sif) {
-                       cam->cam_mode = ov511_vga_mode;
-                       cam->nmodes = ARRAY_SIZE(ov511_vga_mode);
-               } else {
+               if (sd->sif) {
                        cam->cam_mode = ov511_sif_mode;
                        cam->nmodes = ARRAY_SIZE(ov511_sif_mode);
                }
                break;
        case BRIDGE_OV518:
        case BRIDGE_OV518PLUS:
-               if (!sd->sif) {
-                       cam->cam_mode = ov518_vga_mode;
-                       cam->nmodes = ARRAY_SIZE(ov518_vga_mode);
-               } else {
+               if (sd->sif) {
                        cam->cam_mode = ov518_sif_mode;
                        cam->nmodes = ARRAY_SIZE(ov518_sif_mode);
                }
                break;
        case BRIDGE_OV519:
-               if (!sd->sif) {
-                       cam->cam_mode = ov519_vga_mode;
-                       cam->nmodes = ARRAY_SIZE(ov519_vga_mode);
-               } else {
+               if (sd->sif) {
                        cam->cam_mode = ov519_sif_mode;
                        cam->nmodes = ARRAY_SIZE(ov519_sif_mode);
                }
@@ -3077,118 +3065,79 @@ static int sd_config(struct gspca_dev *gspca_dev,
                } else if (sd->sensor == SEN_OV3610) {
                        cam->cam_mode = ovfx2_ov3610_mode;
                        cam->nmodes = ARRAY_SIZE(ovfx2_ov3610_mode);
-               } else if (!sd->sif) {
-                       cam->cam_mode = ov519_vga_mode;
-                       cam->nmodes = ARRAY_SIZE(ov519_vga_mode);
-               } else {
+               } else if (sd->sif) {
                        cam->cam_mode = ov519_sif_mode;
                        cam->nmodes = ARRAY_SIZE(ov519_sif_mode);
                }
                break;
        case BRIDGE_W9968CF:
-               cam->cam_mode = w9968cf_vga_mode;
-               cam->nmodes = ARRAY_SIZE(w9968cf_vga_mode);
                if (sd->sif)
-                       cam->nmodes--;
+                       cam->nmodes = ARRAY_SIZE(w9968cf_vga_mode) - 1;
 
                /* w9968cf needs initialisation once the sensor is known */
-               if (w9968cf_init(sd) < 0)
-                       goto error;
+               w9968cf_init(sd);
                break;
        }
-       gspca_dev->cam.ctrls = sd->ctrls;
-       if (sd->sensor == SEN_OV7670)
-               gspca_dev->ctrl_dis = 1 << COLORS;
-       else
-               gspca_dev->ctrl_dis = (1 << HFLIP) | (1 << VFLIP);
-       sd->quality = QUALITY_DEF;
-       if (sd->sensor == SEN_OV7640 ||
-           sd->sensor == SEN_OV7648)
-               gspca_dev->ctrl_dis |= (1 << AUTOBRIGHT) | (1 << CONTRAST);
-       if (sd->sensor == SEN_OV7670)
-               gspca_dev->ctrl_dis |= 1 << AUTOBRIGHT;
-       /* OV8610 Frequency filter control should work but needs testing */
-       if (sd->sensor == SEN_OV8610)
-               gspca_dev->ctrl_dis |= 1 << FREQ;
-       /* No controls for the OV2610/OV3610 */
-       if (sd->sensor == SEN_OV2610 || sd->sensor == SEN_OV3610)
-               gspca_dev->ctrl_dis |= (1 << NCTRL) - 1;
 
-       return 0;
-error:
-       PDEBUG(D_ERR, "OV519 Config failed");
-       return -EBUSY;
-}
-
-/* this function is called at probe and resume time */
-static int sd_init(struct gspca_dev *gspca_dev)
-{
-       struct sd *sd = (struct sd *) gspca_dev;
+       gspca_dev->ctrl_dis = ctrl_dis[sd->sensor];
 
        /* initialize the sensor */
        switch (sd->sensor) {
        case SEN_OV2610:
-               if (write_i2c_regvals(sd, norm_2610, ARRAY_SIZE(norm_2610)))
-                       return -EIO;
+               write_i2c_regvals(sd, norm_2610, ARRAY_SIZE(norm_2610));
+
                /* Enable autogain, autoexpo, awb, bandfilter */
-               if (i2c_w_mask(sd, 0x13, 0x27, 0x27) < 0)
-                       return -EIO;
+               i2c_w_mask(sd, 0x13, 0x27, 0x27);
                break;
        case SEN_OV3610:
-               if (write_i2c_regvals(sd, norm_3620b, ARRAY_SIZE(norm_3620b)))
-                       return -EIO;
+               write_i2c_regvals(sd, norm_3620b, ARRAY_SIZE(norm_3620b));
+
                /* Enable autogain, autoexpo, awb, bandfilter */
-               if (i2c_w_mask(sd, 0x13, 0x27, 0x27) < 0)
-                       return -EIO;
+               i2c_w_mask(sd, 0x13, 0x27, 0x27);
                break;
        case SEN_OV6620:
-               if (write_i2c_regvals(sd, norm_6x20, ARRAY_SIZE(norm_6x20)))
-                       return -EIO;
+               write_i2c_regvals(sd, norm_6x20, ARRAY_SIZE(norm_6x20));
                break;
        case SEN_OV6630:
        case SEN_OV66308AF:
                sd->ctrls[CONTRAST].def = 200;
                                 /* The default is too low for the ov6630 */
-               if (write_i2c_regvals(sd, norm_6x30, ARRAY_SIZE(norm_6x30)))
-                       return -EIO;
+               write_i2c_regvals(sd, norm_6x30, ARRAY_SIZE(norm_6x30));
                break;
        default:
 /*     case SEN_OV7610: */
 /*     case SEN_OV76BE: */
-               if (write_i2c_regvals(sd, norm_7610, ARRAY_SIZE(norm_7610)))
-                       return -EIO;
-               if (i2c_w_mask(sd, 0x0e, 0x00, 0x40))
-                       return -EIO;
+               write_i2c_regvals(sd, norm_7610, ARRAY_SIZE(norm_7610));
+               i2c_w_mask(sd, 0x0e, 0x00, 0x40);
                break;
        case SEN_OV7620:
        case SEN_OV7620AE:
-               if (write_i2c_regvals(sd, norm_7620, ARRAY_SIZE(norm_7620)))
-                       return -EIO;
+               write_i2c_regvals(sd, norm_7620, ARRAY_SIZE(norm_7620));
                break;
        case SEN_OV7640:
        case SEN_OV7648:
-               if (write_i2c_regvals(sd, norm_7640, ARRAY_SIZE(norm_7640)))
-                       return -EIO;
+               write_i2c_regvals(sd, norm_7640, ARRAY_SIZE(norm_7640));
                break;
        case SEN_OV7670:
                sd->ctrls[FREQ].max = 3;        /* auto */
                sd->ctrls[FREQ].def = 3;
-               if (write_i2c_regvals(sd, norm_7670, ARRAY_SIZE(norm_7670)))
-                       return -EIO;
+               write_i2c_regvals(sd, norm_7670, ARRAY_SIZE(norm_7670));
                break;
        case SEN_OV8610:
-               if (write_i2c_regvals(sd, norm_8610, ARRAY_SIZE(norm_8610)))
-                       return -EIO;
+               write_i2c_regvals(sd, norm_8610, ARRAY_SIZE(norm_8610));
                break;
        }
-       return 0;
+       return gspca_dev->usb_err;
+error:
+       PDEBUG(D_ERR, "OV519 Config failed");
+       return -EINVAL;
 }
 
 /* Set up the OV511/OV511+ with the given image parameters.
  *
  * Do not put any sensor-specific code in here (including I2C I/O functions)
  */
-static int ov511_mode_init_regs(struct sd *sd)
+static void ov511_mode_init_regs(struct sd *sd)
 {
        int hsegs, vsegs, packet_size, fps, needed;
        int interlaced = 0;
@@ -3199,7 +3148,8 @@ static int ov511_mode_init_regs(struct sd *sd)
        alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt);
        if (!alt) {
                err("Couldn't get altsetting");
-               return -EIO;
+               sd->gspca_dev.usb_err = -EIO;
+               return;
        }
 
        packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
@@ -3302,8 +3252,6 @@ static int ov511_mode_init_regs(struct sd *sd)
 
        reg_w(sd, R51x_SYS_RESET, OV511_RESET_OMNICE);
        reg_w(sd, R51x_SYS_RESET, 0);
-
-       return 0;
 }
 
 /* Sets up the OV518/OV518+ with the given image parameters
@@ -3313,7 +3261,7 @@ static int ov511_mode_init_regs(struct sd *sd)
  *
  * Do not put any sensor-specific code in here (including I2C I/O functions)
  */
-static int ov518_mode_init_regs(struct sd *sd)
+static void ov518_mode_init_regs(struct sd *sd)
 {
        int hsegs, vsegs, packet_size;
        struct usb_host_interface *alt;
@@ -3323,14 +3271,14 @@ static int ov518_mode_init_regs(struct sd *sd)
        alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt);
        if (!alt) {
                err("Couldn't get altsetting");
-               return -EIO;
+               sd->gspca_dev.usb_err = -EIO;
+               return;
        }
 
        packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
        ov518_reg_w32(sd, R51x_FIFO_PSIZE, packet_size & ~7, 2);
 
        /******** Set the mode ********/
-
        reg_w(sd, 0x2b, 0);
        reg_w(sd, 0x2c, 0);
        reg_w(sd, 0x2d, 0);
@@ -3364,7 +3312,7 @@ static int ov518_mode_init_regs(struct sd *sd)
        /* Windows driver does this here; who knows why */
        reg_w(sd, 0x2f, 0x80);
 
-       /******** Set the framerate  ********/
+       /******** Set the framerate ********/
        sd->clockdiv = 1;
 
        /* Mode independent, but framerate dependent, regs */
@@ -3427,11 +3375,8 @@ static int ov518_mode_init_regs(struct sd *sd)
        }
 
        reg_w(sd, 0x2f, 0x80);
-
-       return 0;
 }
 
-
 /* Sets up the OV519 with the given image parameters
  *
  * OV519 needs a completely different approach, until we can figure out what
@@ -3439,12 +3384,12 @@ static int ov518_mode_init_regs(struct sd *sd)
  *
  * Do not put any sensor-specific code in here (including I2C I/O functions)
  */
-static int ov519_mode_init_regs(struct sd *sd)
+static void ov519_mode_init_regs(struct sd *sd)
 {
        static const struct ov_regvals mode_init_519_ov7670[] = {
                { 0x5d, 0x03 }, /* Turn off suspend mode */
                { 0x53, 0x9f }, /* was 9b in 1.65-1.08 */
-               { 0x54, 0x0f }, /* bit2 (jpeg enable) */
+               { OV519_R54_EN_CLK1, 0x0f }, /* bit2 (jpeg enable) */
                { 0xa2, 0x20 }, /* a2-a5 are undocumented */
                { 0xa3, 0x18 },
                { 0xa4, 0x04 },
@@ -3467,7 +3412,7 @@ static int ov519_mode_init_regs(struct sd *sd)
        static const struct ov_regvals mode_init_519[] = {
                { 0x5d, 0x03 }, /* Turn off suspend mode */
                { 0x53, 0x9f }, /* was 9b in 1.65-1.08 */
-               { 0x54, 0x0f }, /* bit2 (jpeg enable) */
+               { OV519_R54_EN_CLK1, 0x0f }, /* bit2 (jpeg enable) */
                { 0xa2, 0x20 }, /* a2-a5 are undocumented */
                { 0xa3, 0x18 },
                { 0xa4, 0x04 },
@@ -3487,18 +3432,15 @@ static int ov519_mode_init_regs(struct sd *sd)
 
        /******** Set the mode ********/
        if (sd->sensor != SEN_OV7670) {
-               if (write_regvals(sd, mode_init_519,
-                                 ARRAY_SIZE(mode_init_519)))
-                       return -EIO;
+               write_regvals(sd, mode_init_519, ARRAY_SIZE(mode_init_519));
                if (sd->sensor == SEN_OV7640 ||
                    sd->sensor == SEN_OV7648) {
                        /* Select 8-bit input mode */
                        reg_w_mask(sd, OV519_R20_DFR, 0x10, 0x10);
                }
        } else {
-               if (write_regvals(sd, mode_init_519_ov7670,
-                                 ARRAY_SIZE(mode_init_519_ov7670)))
-                       return -EIO;
+               write_regvals(sd, mode_init_519_ov7670,
+                               ARRAY_SIZE(mode_init_519_ov7670));
        }
 
        reg_w(sd, OV519_R10_H_SIZE,     sd->gspca_dev.width >> 4);
@@ -3594,17 +3536,16 @@ static int ov519_mode_init_regs(struct sd *sd)
                }
                break;
        }
-       return 0;
 }
 
-static int mode_init_ov_sensor_regs(struct sd *sd)
+static void mode_init_ov_sensor_regs(struct sd *sd)
 {
        struct gspca_dev *gspca_dev;
        int qvga, xstart, xend, ystart, yend;
-       __u8 v;
+       u8 v;
 
        gspca_dev = &sd->gspca_dev;
-       qvga = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv & 1;
+       qvga = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv & 1;
 
        /******** Mode (VGA/QVGA) and sensor specific regs ********/
        switch (sd->sensor) {
@@ -3616,7 +3557,7 @@ static int mode_init_ov_sensor_regs(struct sd *sd)
                i2c_w_mask(sd, 0x2d, qvga ? 0x40 : 0x00, 0x40);
                i2c_w_mask(sd, 0x67, qvga ? 0xf0 : 0x90, 0xf0);
                i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20);
-               return 0;
+               return;
        case SEN_OV3610:
                if (qvga) {
                        xstart = (1040 - gspca_dev->width) / 2 + (0x1f << 4);
@@ -3640,7 +3581,7 @@ static int mode_init_ov_sensor_regs(struct sd *sd)
                i2c_w(sd, 0x18, xend >> 4);
                i2c_w(sd, 0x19, ystart >> 3);
                i2c_w(sd, 0x1a, yend >> 3);
-               return 0;
+               return;
        case SEN_OV8610:
                /* For OV8610 qvga means qsvga */
                i2c_w_mask(sd, OV7610_REG_COM_C, qvga ? (1 << 5) : 0, 1 << 5);
@@ -3687,11 +3628,11 @@ static int mode_init_ov_sensor_regs(struct sd *sd)
                /* set COM7_FMT_VGA or COM7_FMT_QVGA
                 * do we need to set anything else?
                 *      HSTART etc are set in set_ov_sensor_window itself */
-               i2c_w_mask(sd, OV7670_REG_COM7,
+               i2c_w_mask(sd, OV7670_R12_COM7,
                         qvga ? OV7670_COM7_FMT_QVGA : OV7670_COM7_FMT_VGA,
                         OV7670_COM7_FMT_MASK);
                i2c_w_mask(sd, 0x13, 0x00, 0x20); /* Select 16 bit data bus */
-               i2c_w_mask(sd, OV7670_REG_COM8, OV7670_COM8_AWB,
+               i2c_w_mask(sd, OV7670_R13_COM8, OV7670_COM8_AWB,
                                OV7670_COM8_AWB);
                if (qvga) {             /* QVGA from ov7670.c by
                                         * Jonathan Corbet */
@@ -3707,21 +3648,21 @@ static int mode_init_ov_sensor_regs(struct sd *sd)
                }
                /* OV7670 hardware window registers are split across
                 * multiple locations */
-               i2c_w(sd, OV7670_REG_HSTART, xstart >> 3);
-               i2c_w(sd, OV7670_REG_HSTOP, xend >> 3);
-               v = i2c_r(sd, OV7670_REG_HREF);
+               i2c_w(sd, OV7670_R17_HSTART, xstart >> 3);
+               i2c_w(sd, OV7670_R18_HSTOP, xend >> 3);
+               v = i2c_r(sd, OV7670_R32_HREF);
                v = (v & 0xc0) | ((xend & 0x7) << 3) | (xstart & 0x07);
                msleep(10);     /* need to sleep between read and write to
                                 * same reg! */
-               i2c_w(sd, OV7670_REG_HREF, v);
+               i2c_w(sd, OV7670_R32_HREF, v);
 
-               i2c_w(sd, OV7670_REG_VSTART, ystart >> 2);
-               i2c_w(sd, OV7670_REG_VSTOP, yend >> 2);
-               v = i2c_r(sd, OV7670_REG_VREF);
+               i2c_w(sd, OV7670_R19_VSTART, ystart >> 2);
+               i2c_w(sd, OV7670_R1A_VSTOP, yend >> 2);
+               v = i2c_r(sd, OV7670_R03_VREF);
                v = (v & 0xc0) | ((yend & 0x3) << 2) | (ystart & 0x03);
                msleep(10);     /* need to sleep between read and write to
                                 * same reg! */
-               i2c_w(sd, OV7670_REG_VREF, v);
+               i2c_w(sd, OV7670_R03_VREF, v);
                break;
        case SEN_OV6620:
                i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
@@ -3734,46 +3675,42 @@ static int mode_init_ov_sensor_regs(struct sd *sd)
                i2c_w_mask(sd, 0x12, 0x04, 0x06); /* AWB: 1 Test pattern: 0 */
                break;
        default:
-               return -EINVAL;
+               return;
        }
 
        /******** Clock programming ********/
        i2c_w(sd, 0x11, sd->clockdiv);
-
-       return 0;
 }
 
 static void sethvflip(struct gspca_dev *gspca_dev)
 {
        struct sd *sd = (struct sd *) gspca_dev;
 
-       if (sd->sensor != SEN_OV7670)
-               return;
        if (sd->gspca_dev.streaming)
-               ov51x_stop(sd);
-       i2c_w_mask(sd, OV7670_REG_MVFP,
+               reg_w(sd, OV519_R51_RESET1, 0x0f);      /* block stream */
+       i2c_w_mask(sd, OV7670_R1E_MVFP,
                OV7670_MVFP_MIRROR * sd->ctrls[HFLIP].val
                        | OV7670_MVFP_VFLIP * sd->ctrls[VFLIP].val,
                OV7670_MVFP_MIRROR | OV7670_MVFP_VFLIP);
        if (sd->gspca_dev.streaming)
-               ov51x_restart(sd);
+               reg_w(sd, OV519_R51_RESET1, 0x00);      /* restart stream */
 }
 
-static int set_ov_sensor_window(struct sd *sd)
+static void set_ov_sensor_window(struct sd *sd)
 {
        struct gspca_dev *gspca_dev;
        int qvga, crop;
        int hwsbase, hwebase, vwsbase, vwebase, hwscale, vwscale;
-       int ret;
 
        /* mode setup is fully handled in mode_init_ov_sensor_regs for these */
        if (sd->sensor == SEN_OV2610 || sd->sensor == SEN_OV3610 ||
-           sd->sensor == SEN_OV7670)
-               return mode_init_ov_sensor_regs(sd);
-
+           sd->sensor == SEN_OV7670) {
+               mode_init_ov_sensor_regs(sd);
+               return;
+       }
        gspca_dev = &sd->gspca_dev;
-       qvga = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv & 1;
-       crop = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv & 2;
+       qvga = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv & 1;
+       crop = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv & 2;
 
        /* The different sensor ICs handle setting up of window differently.
         * IF YOU SET IT WRONG, YOU WILL GET ALL ZERO ISOC DATA FROM OV51x!! */
@@ -3820,7 +3757,7 @@ static int set_ov_sensor_window(struct sd *sd)
                vwsbase = vwebase = 0x03;
                break;
        default:
-               return -EINVAL;
+               return;
        }
 
        switch (sd->sensor) {
@@ -3855,23 +3792,18 @@ static int set_ov_sensor_window(struct sd *sd)
                }
        }
 
-       ret = mode_init_ov_sensor_regs(sd);
-       if (ret < 0)
-               return ret;
+       mode_init_ov_sensor_regs(sd);
 
        i2c_w(sd, 0x17, hwsbase);
        i2c_w(sd, 0x18, hwebase + (sd->sensor_width >> hwscale));
        i2c_w(sd, 0x19, vwsbase);
        i2c_w(sd, 0x1a, vwebase + (sd->sensor_height >> vwscale));
-
-       return 0;
 }
 
 /* -- start the camera -- */
 static int sd_start(struct gspca_dev *gspca_dev)
 {
        struct sd *sd = (struct sd *) gspca_dev;
-       int ret = 0;
 
        /* Default for most bridges, allow bridge_mode_init_regs to override */
        sd->sensor_width = sd->gspca_dev.width;
@@ -3880,50 +3812,46 @@ static int sd_start(struct gspca_dev *gspca_dev)
        switch (sd->bridge) {
        case BRIDGE_OV511:
        case BRIDGE_OV511PLUS:
-               ret = ov511_mode_init_regs(sd);
+               ov511_mode_init_regs(sd);
                break;
        case BRIDGE_OV518:
        case BRIDGE_OV518PLUS:
-               ret = ov518_mode_init_regs(sd);
+               ov518_mode_init_regs(sd);
                break;
        case BRIDGE_OV519:
-               ret = ov519_mode_init_regs(sd);
+               ov519_mode_init_regs(sd);
                break;
        /* case BRIDGE_OVFX2: nothing to do */
        case BRIDGE_W9968CF:
-               ret = w9968cf_mode_init_regs(sd);
+               w9968cf_mode_init_regs(sd);
                break;
        }
-       if (ret < 0)
-               goto out;
-
-       ret = set_ov_sensor_window(sd);
-       if (ret < 0)
-               goto out;
-
-       setcontrast(gspca_dev);
-       setbrightness(gspca_dev);
-       setcolors(gspca_dev);
-       sethvflip(gspca_dev);
-       setautobright(gspca_dev);
-       setfreq_i(sd);
+
+       set_ov_sensor_window(sd);
+
+       if (!(sd->gspca_dev.ctrl_dis & (1 << CONTRAST)))
+               setcontrast(gspca_dev);
+       if (!(sd->gspca_dev.ctrl_dis & (1 << BRIGHTNESS)))
+               setbrightness(gspca_dev);
+       if (!(sd->gspca_dev.ctrl_dis & (1 << COLORS)))
+               setcolors(gspca_dev);
+       if (!(sd->gspca_dev.ctrl_dis & ((1 << HFLIP) | (1 << VFLIP))))
+               sethvflip(gspca_dev);
+       if (!(sd->gspca_dev.ctrl_dis & (1 << AUTOBRIGHT)))
+               setautobright(gspca_dev);
+       if (!(sd->gspca_dev.ctrl_dis & (1 << FREQ)))
+               setfreq_i(sd);
 
        /* Force clear snapshot state in case the snapshot button was
           pressed while we weren't streaming */
        sd->snapshot_needs_reset = 1;
        sd_reset_snapshot(gspca_dev);
-       sd->snapshot_pressed = 0;
 
        sd->first_frame = 3;
 
-       ret = ov51x_restart(sd);
-       if (ret < 0)
-               goto out;
+       ov51x_restart(sd);
        ov51x_led_control(sd, 1);
-       return 0;
-out:
-       PDEBUG(D_ERR, "camera start error:%d", ret);
-       return ret;
+       return gspca_dev->usb_err;
 }
 
 static void sd_stopN(struct gspca_dev *gspca_dev)
@@ -3938,8 +3866,21 @@ static void sd_stop0(struct gspca_dev *gspca_dev)
 {
        struct sd *sd = (struct sd *) gspca_dev;
 
+       if (!sd->gspca_dev.present)
+               return;
        if (sd->bridge == BRIDGE_W9968CF)
                w9968cf_stop0(sd);
+
+#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
+       /* If the last button state is pressed, release it now! */
+       if (sd->snapshot_pressed) {
+               input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
+               input_sync(gspca_dev->input_dev);
+               sd->snapshot_pressed = 0;
+       }
+#endif
+       if (sd->bridge == BRIDGE_OV519)
+               reg_w(sd, OV519_R57_SNAPSHOT, 0x23);
 }
 
 static void ov51x_handle_button(struct gspca_dev *gspca_dev, u8 state)
@@ -4181,8 +4122,8 @@ static void setbrightness(struct gspca_dev *gspca_dev)
                break;
        case SEN_OV7670:
 /*win trace
- *             i2c_w_mask(sd, OV7670_REG_COM8, 0, OV7670_COM8_AEC); */
-               i2c_w(sd, OV7670_REG_BRIGHT, ov7670_abs_to_sm(val));
+ *             i2c_w_mask(sd, OV7670_R13_COM8, 0, OV7670_COM8_AEC); */
+               i2c_w(sd, OV7670_R55_BRIGHT, ov7670_abs_to_sm(val));
                break;
        }
 }
@@ -4203,7 +4144,7 @@ static void setcontrast(struct gspca_dev *gspca_dev)
                i2c_w_mask(sd, OV7610_REG_CNT, val >> 4, 0x0f);
                break;
        case SEN_OV8610: {
-               static const __u8 ctab[] = {
+               static const u8 ctab[] = {
                        0x03, 0x09, 0x0b, 0x0f, 0x53, 0x6f, 0x35, 0x7f
                };
 
@@ -4213,7 +4154,7 @@ static void setcontrast(struct gspca_dev *gspca_dev)
            }
        case SEN_OV7620:
        case SEN_OV7620AE: {
-               static const __u8 ctab[] = {
+               static const u8 ctab[] = {
                        0x01, 0x05, 0x09, 0x11, 0x15, 0x35, 0x37, 0x57,
                        0x5b, 0xa5, 0xa7, 0xc7, 0xc9, 0xcf, 0xef, 0xff
                };
@@ -4224,7 +4165,7 @@ static void setcontrast(struct gspca_dev *gspca_dev)
            }
        case SEN_OV7670:
                /* check that this isn't just the same as ov7610 */
-               i2c_w(sd, OV7670_REG_CONTRAS, val >> 1);
+               i2c_w(sd, OV7670_R56_CONTRAS, val >> 1);
                break;
        }
 }
@@ -4268,38 +4209,30 @@ static void setautobright(struct gspca_dev *gspca_dev)
 {
        struct sd *sd = (struct sd *) gspca_dev;
 
-       if (sd->sensor == SEN_OV7640 || sd->sensor == SEN_OV7648 ||
-           sd->sensor == SEN_OV7670 ||
-           sd->sensor == SEN_OV2610 || sd->sensor == SEN_OV3610)
-               return;
-
        i2c_w_mask(sd, 0x2d, sd->ctrls[AUTOBRIGHT].val ? 0x10 : 0x00, 0x10);
 }
 
 static void setfreq_i(struct sd *sd)
 {
-       if (sd->sensor == SEN_OV2610 || sd->sensor == SEN_OV3610)
-               return;
-
        if (sd->sensor == SEN_OV7670) {
                switch (sd->ctrls[FREQ].val) {
                case 0: /* Banding filter disabled */
-                       i2c_w_mask(sd, OV7670_REG_COM8, 0, OV7670_COM8_BFILT);
+                       i2c_w_mask(sd, OV7670_R13_COM8, 0, OV7670_COM8_BFILT);
                        break;
                case 1: /* 50 hz */
-                       i2c_w_mask(sd, OV7670_REG_COM8, OV7670_COM8_BFILT,
+                       i2c_w_mask(sd, OV7670_R13_COM8, OV7670_COM8_BFILT,
                                   OV7670_COM8_BFILT);
-                       i2c_w_mask(sd, OV7670_REG_COM11, 0x08, 0x18);
+                       i2c_w_mask(sd, OV7670_R3B_COM11, 0x08, 0x18);
                        break;
                case 2: /* 60 hz */
-                       i2c_w_mask(sd, OV7670_REG_COM8, OV7670_COM8_BFILT,
+                       i2c_w_mask(sd, OV7670_R13_COM8, OV7670_COM8_BFILT,
                                   OV7670_COM8_BFILT);
-                       i2c_w_mask(sd, OV7670_REG_COM11, 0x00, 0x18);
+                       i2c_w_mask(sd, OV7670_R3B_COM11, 0x00, 0x18);
                        break;
-               case 3: /* Auto hz */
-                       i2c_w_mask(sd, OV7670_REG_COM8, OV7670_COM8_BFILT,
+               case 3: /* Auto hz - ov7670 only */
+                       i2c_w_mask(sd, OV7670_R13_COM8, OV7670_COM8_BFILT,
                                   OV7670_COM8_BFILT);
-                       i2c_w_mask(sd, OV7670_REG_COM11, OV7670_COM11_HZAUTO,
+                       i2c_w_mask(sd, OV7670_R3B_COM11, OV7670_COM11_HZAUTO,
                                   0x18);
                        break;
                }
@@ -4443,14 +4376,14 @@ static const __devinitdata struct usb_device_id device_table[] = {
        {USB_DEVICE(0x041e, 0x4060), .driver_info = BRIDGE_OV519 },
        {USB_DEVICE(0x041e, 0x4061), .driver_info = BRIDGE_OV519 },
        {USB_DEVICE(0x041e, 0x4064),
-        .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED },
+               .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED },
        {USB_DEVICE(0x041e, 0x4067), .driver_info = BRIDGE_OV519 },
        {USB_DEVICE(0x041e, 0x4068),
-        .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED },
+               .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED },
        {USB_DEVICE(0x045e, 0x028c), .driver_info = BRIDGE_OV519 },
        {USB_DEVICE(0x054c, 0x0154), .driver_info = BRIDGE_OV519 },
        {USB_DEVICE(0x054c, 0x0155),
-        .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED },
+               .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED },
        {USB_DEVICE(0x05a9, 0x0511), .driver_info = BRIDGE_OV511 },
        {USB_DEVICE(0x05a9, 0x0518), .driver_info = BRIDGE_OV518 },
        {USB_DEVICE(0x05a9, 0x0519), .driver_info = BRIDGE_OV519 },
@@ -4464,7 +4397,7 @@ static const __devinitdata struct usb_device_id device_table[] = {
        {USB_DEVICE(0x0b62, 0x0059), .driver_info = BRIDGE_OVFX2 },
        {USB_DEVICE(0x0e96, 0xc001), .driver_info = BRIDGE_OVFX2 },
        {USB_DEVICE(0x1046, 0x9967), .driver_info = BRIDGE_W9968CF },
-       {USB_DEVICE(0x8020, 0xEF04), .driver_info = BRIDGE_OVFX2 },
+       {USB_DEVICE(0x8020, 0xef04), .driver_info = BRIDGE_OVFX2 },
        {}
 };