V4L/DVB (11425): gspca - m5602: Move the vflip quirk to probe stage.
authorErik Andr?n <erik.andren@gmail.com>
Sun, 4 Jan 2009 07:52:50 +0000 (04:52 -0300)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Tue, 7 Apr 2009 00:44:47 +0000 (21:44 -0300)
The vflip quirk is better checked at probe time as it's only needed once.
Also add an extra reset at init time to resolve a suspend to ram regression.

Signed-off-by: Erik Andr?n <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
drivers/media/video/gspca/m5602/m5602_ov9650.c
drivers/media/video/gspca/m5602/m5602_ov9650.h

index 0cff90579772d7add5f612fd5f8e62e2238572b8..9c79a516db6140d7ffcf966494d24f6bdd660ef1 100644 (file)
@@ -65,7 +65,7 @@ static
                        DMI_MATCH(DMI_PRODUCT_NAME, "Aurora m9700")
                }
        },
-       { }
+       {}
 };
 
 const static struct ctrl ov9650_ctrls[] = {
@@ -249,7 +249,7 @@ int ov9650_probe(struct sd *sd)
 
        info("Probing for an ov9650 sensor");
 
-       /* Run the pre-init to actually probe the unit */
+       /* Run the pre-init before probing the sensor */
        for (i = 0; i < ARRAY_SIZE(preinit_ov9650) && !err; i++) {
                u8 data = preinit_ov9650[i][2];
                if (preinit_ov9650[i][0] == SENSOR)
@@ -273,11 +273,9 @@ int ov9650_probe(struct sd *sd)
                info("Detected an ov9650 sensor");
                goto sensor_found;
        }
-
        return -ENODEV;
 
 sensor_found:
-
        sensor_settings = kmalloc(
                ARRAY_SIZE(ov9650_ctrls) * sizeof(s32), GFP_KERNEL);
        if (!sensor_settings)
@@ -292,6 +290,11 @@ sensor_found:
                sensor_settings[i] = ov9650_ctrls[i].qctrl.default_value;
        sd->sensor_priv = sensor_settings;
 
+       if (dmi_check_system(ov9650_flip_dmi_table) && !err) {
+               info("vflip quirk active");
+               sensor_settings[VFLIP_IDX] = 1;
+       }
+
        return 0;
 }
 
@@ -299,6 +302,7 @@ int ov9650_init(struct sd *sd)
 {
        int i, err = 0;
        u8 data;
+       s32 *sensor_settings = sd->sensor_priv;
 
        if (dump_sensor)
                ov9650_dump_registers(sd);
@@ -312,11 +316,35 @@ int ov9650_init(struct sd *sd)
                        err = m5602_write_bridge(sd, init_ov9650[i][1], data);
        }
 
-       if (dmi_check_system(ov9650_flip_dmi_table) && !err) {
-               info("vflip quirk active");
-               data = 0x30;
-               err = m5602_write_sensor(sd, OV9650_MVFP, &data, 1);
-       }
+       err = ov9650_set_exposure(&sd->gspca_dev, sensor_settings[EXPOSURE_IDX]);
+       if (err < 0)
+               return err;
+
+       err = ov9650_set_gain(&sd->gspca_dev, sensor_settings[GAIN_IDX]);
+       if (err < 0)
+               return err;
+
+       err = ov9650_set_red_balance(&sd->gspca_dev, sensor_settings[RED_BALANCE_IDX]);
+       if (err < 0)
+               return err;
+
+       err = ov9650_set_blue_balance(&sd->gspca_dev, sensor_settings[BLUE_BALANCE_IDX]);
+       if (err < 0)
+               return err;
+
+       err = ov9650_set_hflip(&sd->gspca_dev, sensor_settings[HFLIP_IDX]);
+       if (err < 0)
+               return err;
+
+       err = ov9650_set_vflip(&sd->gspca_dev, sensor_settings[VFLIP_IDX]);
+       if (err < 0)
+               return err;
+
+       err = ov9650_set_auto_white_balance(&sd->gspca_dev, sensor_settings[AUTO_WHITE_BALANCE_IDX]);
+       if (err < 0)
+               return err;
+
+       err = ov9650_set_auto_gain(&sd->gspca_dev, sensor_settings[AUTO_GAIN_CTRL_IDX]);
 
        return err;
 }
@@ -339,6 +367,9 @@ int ov9650_start(struct sd *sd)
        if (width <= 320)
                hor_offs /= 2;
 
+       if (err < 0)
+               return err;
+
        /* Synthesize the vsync/hsync setup */
        for (i = 0; i < ARRAY_SIZE(res_init_ov9650) && !err; i++) {
                if (res_init_ov9650[i][0] == BRIDGE)
@@ -635,12 +666,7 @@ int ov9650_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
        if (err < 0)
                return err;
 
-       if (dmi_check_system(ov9650_flip_dmi_table))
-               i2c_data = ((i2c_data & 0xdf) |
-                          (((val ? 0 : 1) & 0x01) << 5));
-       else
-               i2c_data = ((i2c_data & 0xdf) |
-                          ((val & 0x01) << 5));
+       i2c_data = ((i2c_data & 0xdf) | ((val & 0x01) << 5));
 
        err = m5602_write_sensor(sd, OV9650_MVFP, &i2c_data, 1);
 
@@ -672,12 +698,7 @@ int ov9650_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
        if (err < 0)
                return err;
 
-       if (dmi_check_system(ov9650_flip_dmi_table))
-               i2c_data = ((i2c_data & 0xef) |
-                               (((val ? 0 : 1) & 0x01) << 4));
-       else
-               i2c_data = ((i2c_data & 0xef) |
-                               ((val & 0x01) << 4));
+       i2c_data = ((i2c_data & 0xef) | ((val & 0x01) << 4));
 
        err = m5602_write_sensor(sd, OV9650_MVFP, &i2c_data, 1);
 
index 1f27a857bf3f55a8704a4ffede9b2f8288f85e0a..fcc54e4c0f4f33d8e764f85960a4d93fa9229b65 100644 (file)
@@ -218,6 +218,10 @@ static const unsigned char init_ov9650[][3] =
 
        /* Reset chip */
        {SENSOR, OV9650_COM7, OV9650_REGISTER_RESET},
+       /* One extra reset is needed in order to make the sensor behave
+          properly when resuming from ram */
+       {SENSOR, OV9650_COM7, OV9650_REGISTER_RESET},
+
        /* Enable double clock */
        {SENSOR, OV9650_CLKRC, 0x80},
        /* Do something out of spec with the power */