V4L/DVB (11423): gspca - m5602-ov9650: Add a disconnect hook, setup a ctrl cache...
[pandora-kernel.git] / drivers / media / video / gspca / m5602 / m5602_ov9650.h
index 065632f..1f27a85 100644 (file)
@@ -20,7 +20,6 @@
 #define M5602_OV9650_H_
 
 #include <linux/dmi.h>
-
 #include "m5602_sensor.h"
 
 /*****************************************************************************/
 #define OV9650_BAVE                    0x05
 #define OV9650_GEAVE                   0x06
 #define OV9650_RSVD7                   0x07
+#define OV9650_COM2                    0x09
 #define OV9650_PID                     0x0a
 #define OV9650_VER                     0x0b
 #define OV9650_COM3                    0x0c
+#define OV9650_COM4                    0x0d
 #define OV9650_COM5                    0x0e
 #define OV9650_COM6                    0x0f
 #define OV9650_AECH                    0x10
@@ -94,6 +95,9 @@
 
 #define OV9650_REGISTER_RESET          (1 << 7)
 #define OV9650_VGA_SELECT              (1 << 6)
+#define OV9650_CIF_SELECT              (1 << 5)
+#define OV9650_QVGA_SELECT             (1 << 4)
+#define OV9650_QCIF_SELECT             (1 << 3)
 #define OV9650_RGB_SELECT              (1 << 2)
 #define OV9650_RAW_RGB_SELECT          (1 << 0)
 
 #define OV9650_SYSTEM_CLK_SEL          (1 << 7)
 #define OV9650_SLAM_MODE               (1 << 4)
 
+#define OV9650_QVGA_VARIOPIXEL         (1 << 7)
+
 #define OV9650_VFLIP                   (1 << 4)
 #define OV9650_HFLIP                   (1 << 5)
 
+#define OV9650_SOFT_SLEEP              (1 << 4)
+#define OV9650_OUTPUT_DRIVE_2X         (1 << 0)
+
+#define OV9650_LEFT_OFFSET             0x62
+
 #define GAIN_DEFAULT                   0x14
 #define RED_GAIN_DEFAULT               0x70
 #define BLUE_GAIN_DEFAULT              0x20
-#define EXPOSURE_DEFAULT               0x5003
+#define EXPOSURE_DEFAULT               0x1ff
 
 /*****************************************************************************/
 
@@ -124,14 +135,10 @@ extern int dump_sensor;
 
 int ov9650_probe(struct sd *sd);
 int ov9650_init(struct sd *sd);
+int ov9650_start(struct sd *sd);
+int ov9650_stop(struct sd *sd);
 int ov9650_power_down(struct sd *sd);
-
-int ov9650_read_sensor(struct sd *sd, const u8 address,
-                      u8 *i2c_data, const u8 len);
-int ov9650_write_sensor(struct sd *sd, const u8 address,
-                      u8 *i2c_data, const u8 len);
-
-void ov9650_dump_registers(struct sd *sd);
+void ov9650_disconnect(struct sd *sd);
 
 int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val);
 int ov9650_get_exposure(struct gspca_dev *gspca_dev, __s32 *val);
@@ -152,132 +159,16 @@ int ov9650_set_auto_white_balance(struct gspca_dev *gspca_dev, __s32 val);
 int ov9650_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val);
 int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val);
 
-static struct m5602_sensor ov9650 = {
+const static struct m5602_sensor ov9650 = {
        .name = "OV9650",
        .i2c_slave_id = 0x60,
+       .i2c_regW = 1,
        .probe = ov9650_probe,
        .init = ov9650_init,
+       .start = ov9650_start,
+       .stop = ov9650_stop,
        .power_down = ov9650_power_down,
-       .read_sensor = ov9650_read_sensor,
-       .write_sensor = ov9650_write_sensor,
-
-       .nctrls = 8,
-       .ctrls = {
-       {
-               {
-                       .id             = V4L2_CID_EXPOSURE,
-                       .type           = V4L2_CTRL_TYPE_INTEGER,
-                       .name           = "exposure",
-                       .minimum        = 0x00,
-                       .maximum        = 0xffff,
-                       .step           = 0x1,
-                       .default_value  = EXPOSURE_DEFAULT,
-                       .flags          = V4L2_CTRL_FLAG_SLIDER
-               },
-               .set = ov9650_set_exposure,
-               .get = ov9650_get_exposure
-       }, {
-               {
-                       .id             = V4L2_CID_GAIN,
-                       .type           = V4L2_CTRL_TYPE_INTEGER,
-                       .name           = "gain",
-                       .minimum        = 0x00,
-                       .maximum        = 0x3ff,
-                       .step           = 0x1,
-                       .default_value  = GAIN_DEFAULT,
-                       .flags          = V4L2_CTRL_FLAG_SLIDER
-               },
-               .set = ov9650_set_gain,
-               .get = ov9650_get_gain
-       }, {
-               {
-                       .type           = V4L2_CTRL_TYPE_INTEGER,
-                       .name           = "red balance",
-                       .minimum        = 0x00,
-                       .maximum        = 0xff,
-                       .step           = 0x1,
-                       .default_value  = RED_GAIN_DEFAULT,
-                       .flags          = V4L2_CTRL_FLAG_SLIDER
-               },
-               .set = ov9650_set_red_balance,
-               .get = ov9650_get_red_balance
-       }, {
-               {
-                       .type           = V4L2_CTRL_TYPE_INTEGER,
-                       .name           = "blue balance",
-                       .minimum        = 0x00,
-                       .maximum        = 0xff,
-                       .step           = 0x1,
-                       .default_value  = BLUE_GAIN_DEFAULT,
-                       .flags          = V4L2_CTRL_FLAG_SLIDER
-               },
-               .set = ov9650_set_blue_balance,
-               .get = ov9650_get_blue_balance
-       }, {
-               {
-                       .id             = V4L2_CID_HFLIP,
-                       .type           = V4L2_CTRL_TYPE_BOOLEAN,
-                       .name           = "horizontal flip",
-                       .minimum        = 0,
-                       .maximum        = 1,
-                       .step           = 1,
-                       .default_value  = 0
-               },
-               .set = ov9650_set_hflip,
-               .get = ov9650_get_hflip
-       }, {
-               {
-                       .id             = V4L2_CID_VFLIP,
-                       .type           = V4L2_CTRL_TYPE_BOOLEAN,
-                       .name           = "vertical flip",
-                       .minimum        = 0,
-                       .maximum        = 1,
-                       .step           = 1,
-                       .default_value  = 0
-               },
-               .set = ov9650_set_vflip,
-               .get = ov9650_get_vflip
-       }, {
-               {
-                       .id             = V4L2_CID_AUTO_WHITE_BALANCE,
-                       .type           = V4L2_CTRL_TYPE_BOOLEAN,
-                       .name           = "auto white balance",
-                       .minimum        = 0,
-                       .maximum        = 1,
-                       .step           = 1,
-                       .default_value  = 0
-               },
-               .set = ov9650_set_auto_white_balance,
-               .get = ov9650_get_auto_white_balance
-       }, {
-               {
-                       .id             = V4L2_CID_AUTOGAIN,
-                       .type           = V4L2_CTRL_TYPE_BOOLEAN,
-                       .name           = "auto gain control",
-                       .minimum        = 0,
-                       .maximum        = 1,
-                       .step           = 1,
-                       .default_value  = 0
-               },
-               .set = ov9650_set_auto_gain,
-               .get = ov9650_get_auto_gain
-       }
-       },
-
-       .nmodes = 1,
-       .modes = {
-       {
-               M5602_DEFAULT_FRAME_WIDTH,
-               M5602_DEFAULT_FRAME_HEIGHT,
-               V4L2_PIX_FMT_SBGGR8,
-               V4L2_FIELD_NONE,
-               .sizeimage =
-                       M5602_DEFAULT_FRAME_WIDTH * M5602_DEFAULT_FRAME_HEIGHT,
-               .bytesperline = M5602_DEFAULT_FRAME_WIDTH,
-               .colorspace = V4L2_COLORSPACE_SRGB,
-               .priv = 1
-       }
-       }
+       .disconnect = ov9650_disconnect,
 };
 
 static const unsigned char preinit_ov9650[][3] =
@@ -324,6 +215,7 @@ static const unsigned char init_ov9650[][3] =
        {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00},
        {BRIDGE, M5602_XB_GPIO_DAT, 0x00},
        {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a},
+
        /* Reset chip */
        {SENSOR, OV9650_COM7, OV9650_REGISTER_RESET},
        /* Enable double clock */
@@ -331,8 +223,6 @@ static const unsigned char init_ov9650[][3] =
        /* Do something out of spec with the power */
        {SENSOR, OV9650_OFON, 0x40},
 
-       /* Set QQVGA */
-       {SENSOR, OV9650_COM1, 0x20},
        /* Set fast AGC/AEC algorithm with unlimited step size */
        {SENSOR, OV9650_COM8, OV9650_FAST_AGC_AEC |
                              OV9650_AEC_UNLIM_STEP_SIZE |
@@ -343,7 +233,7 @@ static const unsigned char init_ov9650[][3] =
        {SENSOR, OV9650_ACOM38, 0x81},
        /* Turn off color matrix coefficient double option */
        {SENSOR, OV9650_COM16, 0x00},
-               /* Enable color matrix for RGB/YUV, Delay Y channel,
+       /* Enable color matrix for RGB/YUV, Delay Y channel,
        set output Y/UV delay to 1 */
        {SENSOR, OV9650_COM13, 0x19},
        /* Enable digital BLC, Set output mode to U Y V Y */
@@ -352,7 +242,7 @@ static const unsigned char init_ov9650[][3] =
        {SENSOR, OV9650_COM24, 0x00},
        /* Enable HREF and some out of spec things */
        {SENSOR, OV9650_COM12, 0x73},
-               /* Set all DBLC offset signs to positive and
+       /* Set all DBLC offset signs to positive and
        do some out of spec stuff */
        {SENSOR, OV9650_DBLC1, 0xdf},
        {SENSOR, OV9650_COM21, 0x06},
@@ -364,7 +254,7 @@ static const unsigned char init_ov9650[][3] =
        {SENSOR, OV9650_RSVD96, 0x04},
        /* Enable full range output */
        {SENSOR, OV9650_COM15, 0x0},
-               /* Enable HREF at optical black, enable ADBLC bias,
+       /* Enable HREF at optical black, enable ADBLC bias,
        enable ADBLC, reset timings at format change */
        {SENSOR, OV9650_COM6, 0x4b},
        /* Subtract 32 from the B channel bias */
@@ -385,7 +275,7 @@ static const unsigned char init_ov9650[][3] =
        {SENSOR, OV9650_AEB, 0x5c},
        /* Set the high and low limit nibbles to 3 */
        {SENSOR, OV9650_VPT, 0xc3},
-               /* Set the Automatic Gain Ceiling (AGC) to 128x,
+       /* Set the Automatic Gain Ceiling (AGC) to 128x,
        drop VSYNC at frame drop,
        limit exposure timing,
        drop frame when the AEC step is larger than the exposure gap */
@@ -394,9 +284,9 @@ static const unsigned char init_ov9650[][3] =
        and set PWDN to SLVS (slave mode vertical sync) */
        {SENSOR, OV9650_COM10, 0x42},
        /* Set horizontal column start high to default value */
-       {SENSOR, OV9650_HSTART, 0x1a},
+       {SENSOR, OV9650_HSTART, 0x1a}, /* 210 */
        /* Set horizontal column end */
-       {SENSOR, OV9650_HSTOP, 0xbf},
+       {SENSOR, OV9650_HSTOP, 0xbf}, /* 1534 */
        /* Complementing register to the two writes above */
        {SENSOR, OV9650_HREF, 0xb2},
        /* Set vertical row start high bits */
@@ -405,42 +295,17 @@ static const unsigned char init_ov9650[][3] =
        {SENSOR, OV9650_VSTOP, 0x7e},
        /* Set complementing vertical frame control */
        {SENSOR, OV9650_VREF, 0x10},
-       /* Set raw RGB output format with VGA resolution */
-       {SENSOR, OV9650_COM7, OV9650_VGA_SELECT |
-                             OV9650_RGB_SELECT |
-                             OV9650_RAW_RGB_SELECT},
        {SENSOR, OV9650_ADC, 0x04},
        {SENSOR, OV9650_HV, 0x40},
        /* Enable denoise, and white-pixel erase */
        {SENSOR, OV9650_COM22, 0x23},
 
-       /* Set the high bits of the exposure value */
-       {SENSOR, OV9650_AECH, ((EXPOSURE_DEFAULT & 0xff00) >> 8)},
-
-       /* Set the low bits of the exposure value */
-       {SENSOR, OV9650_COM1, (EXPOSURE_DEFAULT & 0xff)},
-       {SENSOR, OV9650_GAIN, GAIN_DEFAULT},
-       {SENSOR, OV9650_BLUE, BLUE_GAIN_DEFAULT},
-       {SENSOR, OV9650_RED, RED_GAIN_DEFAULT},
-
+       /* Enable VARIOPIXEL */
        {SENSOR, OV9650_COM3, OV9650_VARIOPIXEL},
-       {SENSOR, OV9650_COM5, OV9650_SYSTEM_CLK_SEL},
+       {SENSOR, OV9650_COM4, OV9650_QVGA_VARIOPIXEL},
 
-       {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x82},
-       {BRIDGE, M5602_XB_LINE_OF_FRAME_L, 0x00},
-       {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82},
-       {BRIDGE, M5602_XB_PIX_OF_LINE_L, 0x00},
-       {BRIDGE, M5602_XB_SIG_INI, 0x01},
-       {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
-       {BRIDGE, M5602_XB_VSYNC_PARA, 0x09},
-       {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
-       {BRIDGE, M5602_XB_VSYNC_PARA, 0x01},
-       {BRIDGE, M5602_XB_VSYNC_PARA, 0xe0},
-       {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
-       {BRIDGE, M5602_XB_HSYNC_PARA, 0x00},
-       {BRIDGE, M5602_XB_HSYNC_PARA, 0x5e},
-       {BRIDGE, M5602_XB_HSYNC_PARA, 0x02},
-       {BRIDGE, M5602_XB_HSYNC_PARA, 0xde}
+       /* Put the sensor in soft sleep mode */
+       {SENSOR, OV9650_COM2, OV9650_SOFT_SLEEP | OV9650_OUTPUT_DRIVE_2X},
 };
 
 static const unsigned char power_down_ov9650[][3] =
@@ -460,43 +325,18 @@ static const unsigned char power_down_ov9650[][3] =
        {BRIDGE, M5602_XB_GPIO_EN_L, 0x06},
        {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02},
        {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04},
-       {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}
+       {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
 };
 
-/* Vertically and horizontally flips the image if matched, needed for machines
-   where the sensor is mounted upside down */
-static
-    const
-       struct dmi_system_id ov9650_flip_dmi_table[] = {
-       {
-               .ident = "ASUS A6VC",
-               .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "A6VC")
-               }
-       },
-       {
-               .ident = "ASUS A6VM",
-               .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "A6VM")
-               }
-       },
-       {
-               .ident = "ASUS A6JC",
-               .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "A6JC")
-               }
-       },
-       {
-               .ident = "ASUS A6Kt",
-               .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "A6Kt")
-               }
-       },
-       { }
+static const unsigned char res_init_ov9650[][3] =
+{
+       {SENSOR, OV9650_COM2, OV9650_OUTPUT_DRIVE_2X},
+
+       {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x82},
+       {BRIDGE, M5602_XB_LINE_OF_FRAME_L, 0x00},
+       {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82},
+       {BRIDGE, M5602_XB_PIX_OF_LINE_L, 0x00},
+       {BRIDGE, M5602_XB_SIG_INI, 0x01}
 };
 
 #endif