V4L/DVB (12082): gspca_stv06xx: Add support for st6422 bridge and sensor
[linux-2.6.git] / drivers / media / video / gspca / stv06xx / stv06xx_hdcs.c
index 1cfe585..3039ec2 100644 (file)
 
 #include "stv06xx_hdcs.h"
 
+static const struct ctrl hdcs1x00_ctrl[] = {
+       {
+               {
+                       .id             = V4L2_CID_EXPOSURE,
+                       .type           = V4L2_CTRL_TYPE_INTEGER,
+                       .name           = "exposure",
+                       .minimum        = 0x00,
+                       .maximum        = 0xffff,
+                       .step           = 0x1,
+                       .default_value  = HDCS_DEFAULT_EXPOSURE,
+                       .flags          = V4L2_CTRL_FLAG_SLIDER
+               },
+               .set = hdcs_set_exposure,
+               .get = hdcs_get_exposure
+       }, {
+               {
+                       .id             = V4L2_CID_GAIN,
+                       .type           = V4L2_CTRL_TYPE_INTEGER,
+                       .name           = "gain",
+                       .minimum        = 0x00,
+                       .maximum        = 0xff,
+                       .step           = 0x1,
+                       .default_value  = HDCS_DEFAULT_GAIN,
+                       .flags          = V4L2_CTRL_FLAG_SLIDER
+               },
+               .set = hdcs_set_gain,
+               .get = hdcs_get_gain
+       }
+};
+
+static struct v4l2_pix_format hdcs1x00_mode[] = {
+       {
+               HDCS_1X00_DEF_WIDTH,
+               HDCS_1X00_DEF_HEIGHT,
+               V4L2_PIX_FMT_SBGGR8,
+               V4L2_FIELD_NONE,
+               .sizeimage =
+                       HDCS_1X00_DEF_WIDTH * HDCS_1X00_DEF_HEIGHT,
+               .bytesperline = HDCS_1X00_DEF_WIDTH,
+               .colorspace = V4L2_COLORSPACE_SRGB,
+               .priv = 1
+       }
+};
+
+static const struct ctrl hdcs1020_ctrl[] = {};
+
+static struct v4l2_pix_format hdcs1020_mode[] = {
+       {
+               HDCS_1020_DEF_WIDTH,
+               HDCS_1020_DEF_HEIGHT,
+               V4L2_PIX_FMT_SBGGR8,
+               V4L2_FIELD_NONE,
+               .sizeimage =
+                       HDCS_1020_DEF_WIDTH * HDCS_1020_DEF_HEIGHT,
+               .bytesperline = HDCS_1020_DEF_WIDTH,
+               .colorspace = V4L2_COLORSPACE_SRGB,
+               .priv = 1
+       }
+};
+
 enum hdcs_power_state {
        HDCS_STATE_SLEEP,
        HDCS_STATE_IDLE,
@@ -317,8 +377,10 @@ static int hdcs_set_size(struct sd *sd,
 
                y = (hdcs->array.height - HDCS_1020_BOTTOM_Y_SKIP - height) / 2
                                + hdcs->array.top;
-       } else if (height > hdcs->array.height) {
-               height = hdcs->array.height;
+       } else {
+               if (height > hdcs->array.height)
+                       height = hdcs->array.height;
+
                y = hdcs->array.top + (hdcs->array.height - height) / 2;
        }
 
@@ -351,10 +413,10 @@ static int hdcs_probe_1x00(struct sd *sd)
 
        info("HDCS-1000/1100 sensor detected");
 
-       sd->gspca_dev.cam.cam_mode = stv06xx_sensor_hdcs1x00.modes;
-       sd->gspca_dev.cam.nmodes = stv06xx_sensor_hdcs1x00.nmodes;
-       sd->desc.ctrls = stv06xx_sensor_hdcs1x00.ctrls;
-       sd->desc.nctrls = stv06xx_sensor_hdcs1x00.nctrls;
+       sd->gspca_dev.cam.cam_mode = hdcs1x00_mode;
+       sd->gspca_dev.cam.nmodes = ARRAY_SIZE(hdcs1x00_mode);
+       sd->desc.ctrls = hdcs1x00_ctrl;
+       sd->desc.nctrls = ARRAY_SIZE(hdcs1x00_ctrl);
 
        hdcs = kmalloc(sizeof(struct hdcs), GFP_KERNEL);
        if (!hdcs)
@@ -372,7 +434,7 @@ static int hdcs_probe_1x00(struct sd *sd)
        hdcs->exp.er = 100;
 
        /*
-        * Frame rate on HDCS-1000 0x46D:0x840 depends on PSMP:
+        * Frame rate on HDCS-1000 with STV600 depends on PSMP:
         *  4 = doesn't work at all
         *  5 = 7.8 fps,
         *  6 = 6.9 fps,
@@ -381,7 +443,7 @@ static int hdcs_probe_1x00(struct sd *sd)
         * 15 = 4.4 fps,
         * 31 = 2.8 fps
         *
-        * Frame rate on HDCS-1000 0x46D:0x870 depends on PSMP:
+        * Frame rate on HDCS-1000 with STV602 depends on PSMP:
         * 15 = doesn't work at all
         * 18 = doesn't work at all
         * 19 = 7.3 fps
@@ -391,7 +453,7 @@ static int hdcs_probe_1x00(struct sd *sd)
         * 24 = 6.3 fps
         * 30 = 5.4 fps
         */
-       hdcs->psmp = IS_870(sd) ? 20 : 5;
+       hdcs->psmp = (sd->bridge == BRIDGE_STV602) ? 20 : 5;
 
        sd->sensor_priv = hdcs;
 
@@ -410,10 +472,10 @@ static int hdcs_probe_1020(struct sd *sd)
 
        info("HDCS-1020 sensor detected");
 
-       sd->gspca_dev.cam.cam_mode = stv06xx_sensor_hdcs1020.modes;
-       sd->gspca_dev.cam.nmodes = stv06xx_sensor_hdcs1020.nmodes;
-       sd->desc.ctrls = stv06xx_sensor_hdcs1020.ctrls;
-       sd->desc.nctrls = stv06xx_sensor_hdcs1020.nctrls;
+       sd->gspca_dev.cam.cam_mode = hdcs1020_mode;
+       sd->gspca_dev.cam.nmodes = ARRAY_SIZE(hdcs1020_mode);
+       sd->desc.ctrls = hdcs1020_ctrl;
+       sd->desc.nctrls = ARRAY_SIZE(hdcs1020_ctrl);
 
        hdcs = kmalloc(sizeof(struct hdcs), GFP_KERNEL);
        if (!hdcs)
@@ -468,7 +530,7 @@ static int hdcs_init(struct sd *sd)
        int i, err = 0;
 
        /* Set the STV0602AA in STV0600 emulation mode */
-       if (IS_870(sd))
+       if (sd->bridge == BRIDGE_STV602)
                stv06xx_write_bridge(sd, STV_STV0600_EMULATION, 1);
 
        /* Execute the bridge init */
@@ -496,7 +558,7 @@ static int hdcs_init(struct sd *sd)
                return err;
 
        /* Set PGA sample duration
-       (was 0x7E for IS_870, but caused slow framerate with HDCS-1020) */
+       (was 0x7E for the STV602, but caused slow framerate with HDCS-1020) */
        if (IS_1020(sd))
                err = stv06xx_write_sensor(sd, HDCS_TCTRL,
                                (HDCS_ADC_START_SIG_DUR << 6) | hdcs->psmp);