[media] gspca - stv06xx/st6422: Use the new video control mechanism
Jean-Fran├žois Moine [Tue, 28 Dec 2010 10:35:27 +0000 (07:35 -0300)]
Signed-off-by: Jean-Fran├žois Moine <moinejf@free.fr>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>

drivers/media/video/gspca/stv06xx/stv06xx_st6422.c
drivers/media/video/gspca/stv06xx/stv06xx_st6422.h

index 42f3a1e..8a456de 100644 (file)
 
 #include "stv06xx_st6422.h"
 
+/* controls */
+enum e_ctrl {
+       BRIGHTNESS,
+       CONTRAST,
+       GAIN,
+       EXPOSURE,
+       NCTRLS          /* number of controls */
+};
+
+/* sensor settings */
+struct st6422_settings {
+       struct gspca_ctrl ctrls[NCTRLS];
+};
+
 static struct v4l2_pix_format st6422_mode[] = {
        /* Note we actually get 124 lines of data, of which we skip the 4st
           4 as they are garbage */
@@ -57,9 +71,14 @@ static struct v4l2_pix_format st6422_mode[] = {
        },
 };
 
-static const struct ctrl st6422_ctrl[] = {
-#define BRIGHTNESS_IDX 0
-       {
+/* V4L2 controls supported by the driver */
+static void st6422_set_brightness(struct gspca_dev *gspca_dev);
+static void st6422_set_contrast(struct gspca_dev *gspca_dev);
+static void st6422_set_gain(struct gspca_dev *gspca_dev);
+static void st6422_set_exposure(struct gspca_dev *gspca_dev);
+
+static const struct ctrl st6422_ctrl[NCTRLS] = {
+[BRIGHTNESS] = {
                {
                        .id             = V4L2_CID_BRIGHTNESS,
                        .type           = V4L2_CTRL_TYPE_INTEGER,
@@ -69,11 +88,9 @@ static const struct ctrl st6422_ctrl[] = {
                        .step           = 1,
                        .default_value  = 3
                },
-               .set = st6422_set_brightness,
-               .get = st6422_get_brightness
+               .set_control = st6422_set_brightness
        },
-#define CONTRAST_IDX 1
-       {
+[CONTRAST] = {
                {
                        .id             = V4L2_CID_CONTRAST,
                        .type           = V4L2_CTRL_TYPE_INTEGER,
@@ -83,11 +100,9 @@ static const struct ctrl st6422_ctrl[] = {
                        .step           = 1,
                        .default_value  = 11
                },
-               .set = st6422_set_contrast,
-               .get = st6422_get_contrast
+               .set_control = st6422_set_contrast
        },
-#define GAIN_IDX 2
-       {
+[GAIN] = {
                {
                        .id             = V4L2_CID_GAIN,
                        .type           = V4L2_CTRL_TYPE_INTEGER,
@@ -97,49 +112,43 @@ static const struct ctrl st6422_ctrl[] = {
                        .step           = 1,
                        .default_value  = 64
                },
-               .set = st6422_set_gain,
-               .get = st6422_get_gain
+               .set_control = st6422_set_gain
        },
-#define EXPOSURE_IDX 3
-       {
+[EXPOSURE] = {
                {
                        .id             = V4L2_CID_EXPOSURE,
                        .type           = V4L2_CTRL_TYPE_INTEGER,
                        .name           = "Exposure",
                        .minimum        = 0,
-                       .maximum        = 1023,
+#define EXPOSURE_MAX 1023
+                       .maximum        = EXPOSURE_MAX,
                        .step           = 1,
                        .default_value  = 256
                },
-               .set = st6422_set_exposure,
-               .get = st6422_get_exposure
+               .set_control = st6422_set_exposure
        },
 };
 
 static int st6422_probe(struct sd *sd)
 {
-       int i;
-       s32 *sensor_settings;
+       struct st6422_settings *sensor_settings;
 
        if (sd->bridge != BRIDGE_ST6422)
                return -ENODEV;
 
        info("st6422 sensor detected");
 
-       sensor_settings = kmalloc(ARRAY_SIZE(st6422_ctrl) * sizeof(s32),
-                                 GFP_KERNEL);
+       sensor_settings = kmalloc(sizeof *sensor_settings, GFP_KERNEL);
        if (!sensor_settings)
                return -ENOMEM;
 
        sd->gspca_dev.cam.cam_mode = st6422_mode;
        sd->gspca_dev.cam.nmodes = ARRAY_SIZE(st6422_mode);
+       sd->gspca_dev.cam.ctrls = sensor_settings->ctrls;
        sd->desc.ctrls = st6422_ctrl;
        sd->desc.nctrls = ARRAY_SIZE(st6422_ctrl);
        sd->sensor_priv = sensor_settings;
 
-       for (i = 0; i < sd->desc.nctrls; i++)
-               sensor_settings[i] = st6422_ctrl[i].qctrl.default_value;
-
        return 0;
 }
 
@@ -234,77 +243,92 @@ static void st6422_disconnect(struct sd *sd)
        kfree(sd->sensor_priv);
 }
 
-static int st6422_start(struct sd *sd)
+static int setbrightness(struct sd *sd)
+{
+       struct st6422_settings *sensor_settings = sd->sensor_priv;
+
+       /* val goes from 0 -> 31 */
+       return stv06xx_write_bridge(sd, 0x1432,
+                       sensor_settings->ctrls[BRIGHTNESS].val);
+}
+
+static int setcontrast(struct sd *sd)
+{
+       struct st6422_settings *sensor_settings = sd->sensor_priv;
+
+       /* Val goes from 0 -> 15 */
+       return stv06xx_write_bridge(sd, 0x143a,
+                       sensor_settings->ctrls[CONTRAST].val | 0xf0);
+}
+
+static int setgain(struct sd *sd)
 {
+       struct st6422_settings *sensor_settings = sd->sensor_priv;
+       u8 gain;
        int err;
-       struct cam *cam = &sd->gspca_dev.cam;
-       s32 *sensor_settings = sd->sensor_priv;
 
-       if (cam->cam_mode[sd->gspca_dev.curr_mode].priv)
-               err = stv06xx_write_bridge(sd, 0x1505, 0x0f);
-       else
-               err = stv06xx_write_bridge(sd, 0x1505, 0x02);
-       if (err < 0)
-               return err;
+       gain = sensor_settings->ctrls[GAIN].val;
 
-       err = st6422_set_brightness(&sd->gspca_dev,
-                                   sensor_settings[BRIGHTNESS_IDX]);
+       /* Set red, green, blue, gain */
+       err = stv06xx_write_bridge(sd, 0x0509, gain);
        if (err < 0)
                return err;
 
-       err = st6422_set_contrast(&sd->gspca_dev,
-                                 sensor_settings[CONTRAST_IDX]);
+       err = stv06xx_write_bridge(sd, 0x050a, gain);
        if (err < 0)
                return err;
 
-       err = st6422_set_exposure(&sd->gspca_dev,
-                                 sensor_settings[EXPOSURE_IDX]);
+       err = stv06xx_write_bridge(sd, 0x050b, gain);
        if (err < 0)
                return err;
 
-       err = st6422_set_gain(&sd->gspca_dev,
-                             sensor_settings[GAIN_IDX]);
+       /* 2 mystery writes */
+       err = stv06xx_write_bridge(sd, 0x050c, 0x2a);
        if (err < 0)
                return err;
 
-       PDEBUG(D_STREAM, "Starting stream");
-
-       return 0;
+       return stv06xx_write_bridge(sd, 0x050d, 0x01);
 }
 
-static int st6422_stop(struct sd *sd)
+static int setexposure(struct sd *sd)
 {
-       PDEBUG(D_STREAM, "Halting stream");
-
-       return 0;
-}
-
-static int st6422_get_brightness(struct gspca_dev *gspca_dev, __s32 *val)
-{
-       struct sd *sd = (struct sd *) gspca_dev;
-       s32 *sensor_settings = sd->sensor_priv;
-
-       *val = sensor_settings[BRIGHTNESS_IDX];
+       struct st6422_settings *sensor_settings = sd->sensor_priv;
+       u16 expo;
+       int err;
 
-       PDEBUG(D_V4L2, "Read brightness %d", *val);
+       expo = sensor_settings->ctrls[EXPOSURE].val;
+       err = stv06xx_write_bridge(sd, 0x143d, expo & 0xff);
+       if (err < 0)
+               return err;
 
-       return 0;
+       return stv06xx_write_bridge(sd, 0x143e, expo >> 8);
 }
 
-static int st6422_set_brightness(struct gspca_dev *gspca_dev, __s32 val)
+static int st6422_start(struct sd *sd)
 {
        int err;
-       struct sd *sd = (struct sd *) gspca_dev;
-       s32 *sensor_settings = sd->sensor_priv;
+       struct cam *cam = &sd->gspca_dev.cam;
 
-       sensor_settings[BRIGHTNESS_IDX] = val;
+       if (cam->cam_mode[sd->gspca_dev.curr_mode].priv)
+               err = stv06xx_write_bridge(sd, 0x1505, 0x0f);
+       else
+               err = stv06xx_write_bridge(sd, 0x1505, 0x02);
+       if (err < 0)
+               return err;
 
-       if (!gspca_dev->streaming)
-               return 0;
+       err = setbrightness(sd);
+       if (err < 0)
+               return err;
 
-       /* val goes from 0 -> 31 */
-       PDEBUG(D_V4L2, "Set brightness to %d", val);
-       err = stv06xx_write_bridge(sd, 0x1432, val);
+       err = setcontrast(sd);
+       if (err < 0)
+               return err;
+
+       err = setexposure(sd);
+       if (err < 0)
+               return err;
+
+       err = setgain(sd);
        if (err < 0)
                return err;
 
@@ -313,125 +337,65 @@ static int st6422_set_brightness(struct gspca_dev *gspca_dev, __s32 val)
        return (err < 0) ? err : 0;
 }
 
-static int st6422_get_contrast(struct gspca_dev *gspca_dev, __s32 *val)
+static int st6422_stop(struct sd *sd)
 {
-       struct sd *sd = (struct sd *) gspca_dev;
-       s32 *sensor_settings = sd->sensor_priv;
-
-       *val = sensor_settings[CONTRAST_IDX];
-
-       PDEBUG(D_V4L2, "Read contrast %d", *val);
+       PDEBUG(D_STREAM, "Halting stream");
 
        return 0;
 }
 
-static int st6422_set_contrast(struct gspca_dev *gspca_dev, __s32 val)
+static void st6422_set_brightness(struct gspca_dev *gspca_dev)
 {
        int err;
        struct sd *sd = (struct sd *) gspca_dev;
-       s32 *sensor_settings = sd->sensor_priv;
-
-       sensor_settings[CONTRAST_IDX] = val;
 
-       if (!gspca_dev->streaming)
-               return 0;
-
-       /* Val goes from 0 -> 15 */
-       PDEBUG(D_V4L2, "Set contrast to %d\n", val);
-       err = stv06xx_write_bridge(sd, 0x143a, 0xf0 | val);
-       if (err < 0)
-               return err;
+       err = setbrightness(sd);
 
        /* commit settings */
-       err = stv06xx_write_bridge(sd, 0x143f, 0x01);
-       return (err < 0) ? err : 0;
-}
-
-static int st6422_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
-{
-       struct sd *sd = (struct sd *) gspca_dev;
-       s32 *sensor_settings = sd->sensor_priv;
-
-       *val = sensor_settings[GAIN_IDX];
+       if (err >= 0)
+               err = stv06xx_write_bridge(sd, 0x143f, 0x01);
 
-       PDEBUG(D_V4L2, "Read gain %d", *val);
-
-       return 0;
+       gspca_dev->usb_err = err;
 }
 
-static int st6422_set_gain(struct gspca_dev *gspca_dev, __s32 val)
+static void st6422_set_contrast(struct gspca_dev *gspca_dev)
 {
        int err;
        struct sd *sd = (struct sd *) gspca_dev;
-       s32 *sensor_settings = sd->sensor_priv;
 
-       sensor_settings[GAIN_IDX] = val;
-
-       if (!gspca_dev->streaming)
-               return 0;
-
-       PDEBUG(D_V4L2, "Set gain to %d", val);
-
-       /* Set red, green, blue, gain */
-       err = stv06xx_write_bridge(sd, 0x0509, val);
-       if (err < 0)
-               return err;
-
-       err = stv06xx_write_bridge(sd, 0x050a, val);
-       if (err < 0)
-               return err;
-
-       err = stv06xx_write_bridge(sd, 0x050b, val);
-       if (err < 0)
-               return err;
-
-       /* 2 mystery writes */
-       err = stv06xx_write_bridge(sd, 0x050c, 0x2a);
-       if (err < 0)
-               return err;
-
-       err = stv06xx_write_bridge(sd, 0x050d, 0x01);
-       if (err < 0)
-               return err;
+       err = setcontrast(sd);
 
        /* commit settings */
-       err = stv06xx_write_bridge(sd, 0x143f, 0x01);
-       return (err < 0) ? err : 0;
+       if (err >= 0)
+               err = stv06xx_write_bridge(sd, 0x143f, 0x01);
+
+       gspca_dev->usb_err = err;
 }
 
-static int st6422_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
+static void st6422_set_gain(struct gspca_dev *gspca_dev)
 {
+       int err;
        struct sd *sd = (struct sd *) gspca_dev;
-       s32 *sensor_settings = sd->sensor_priv;
 
-       *val = sensor_settings[EXPOSURE_IDX];
+       err = setgain(sd);
 
-       PDEBUG(D_V4L2, "Read exposure %d", *val);
+       /* commit settings */
+       if (err >= 0)
+               err = stv06xx_write_bridge(sd, 0x143f, 0x01);
 
-       return 0;
+       gspca_dev->usb_err = err;
 }
 
-static int st6422_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
+static void st6422_set_exposure(struct gspca_dev *gspca_dev)
 {
        int err;
        struct sd *sd = (struct sd *) gspca_dev;
-       s32 *sensor_settings = sd->sensor_priv;
-
-       sensor_settings[EXPOSURE_IDX] = val;
-
-       if (!gspca_dev->streaming)
-               return 0;
-
-       PDEBUG(D_V4L2, "Set exposure to %d\n", val);
-       err = stv06xx_write_bridge(sd, 0x143d, val & 0xff);
-       if (err < 0)
-               return err;
 
-       err = stv06xx_write_bridge(sd, 0x143e, val >> 8);
-       if (err < 0)
-               return err;
+       err = setexposure(sd);
 
        /* commit settings */
-       err = stv06xx_write_bridge(sd, 0x143f, 0x01);
-       return (err < 0) ? err : 0;
+       if (err >= 0)
+               err = stv06xx_write_bridge(sd, 0x143f, 0x01);
+
+       gspca_dev->usb_err = err;
 }
index 12608ae..d7498e0 100644 (file)
@@ -37,16 +37,6 @@ static int st6422_init(struct sd *sd);
 static int st6422_stop(struct sd *sd);
 static void st6422_disconnect(struct sd *sd);
 
-/* V4L2 controls supported by the driver */
-static int st6422_get_brightness(struct gspca_dev *gspca_dev, __s32 *val);
-static int st6422_set_brightness(struct gspca_dev *gspca_dev, __s32 val);
-static int st6422_get_contrast(struct gspca_dev *gspca_dev, __s32 *val);
-static int st6422_set_contrast(struct gspca_dev *gspca_dev, __s32 val);
-static int st6422_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
-static int st6422_set_gain(struct gspca_dev *gspca_dev, __s32 val);
-static int st6422_get_exposure(struct gspca_dev *gspca_dev, __s32 *val);
-static int st6422_set_exposure(struct gspca_dev *gspca_dev, __s32 val);
-
 const struct stv06xx_sensor stv06xx_sensor_st6422 = {
        .name = "ST6422",
        /* No known way to lower framerate in case of less bandwidth */