V4L/DVB (12512): ov772x: implement a band-stop filter support
authorGuennadi Liakhovetski <g.liakhovetski@gmx.de>
Tue, 25 Aug 2009 14:44:14 +0000 (11:44 -0300)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Sat, 19 Sep 2009 03:18:38 +0000 (00:18 -0300)
The V4L2_CID_BAND_STOP_FILTER control is used to switch the "Banding Filter" on
OV772x cameras on and off and to set the minimum AEC value in BDBASE register.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
drivers/media/video/ov772x.c

index 119159773a68fea92f1e30334fade584c2491416..4c550f91ca24d27a7a194bcca7eba10e98c4ab91 100644 (file)
@@ -403,8 +403,9 @@ struct ov772x_priv {
        const struct ov772x_color_format *fmt;
        const struct ov772x_win_size     *win;
        int                               model;
-       unsigned int                      flag_vflip:1;
-       unsigned int                      flag_hflip:1;
+       unsigned short                    flag_vflip:1;
+       unsigned short                    flag_hflip:1;
+       unsigned short                    band_filter;  /* 256 - BDBASE, 0 if (!COM8[5]) */
 };
 
 #define ENDMARKER { 0xff, 0xff }
@@ -569,6 +570,15 @@ static const struct v4l2_queryctrl ov772x_controls[] = {
                .step           = 1,
                .default_value  = 0,
        },
+       {
+               .id             = V4L2_CID_BAND_STOP_FILTER,
+               .type           = V4L2_CTRL_TYPE_INTEGER,
+               .name           = "Band-stop filter",
+               .minimum        = 0,
+               .maximum        = 256,
+               .step           = 1,
+               .default_value  = 0,
+       },
 };
 
 
@@ -674,6 +684,9 @@ static int ov772x_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
        case V4L2_CID_HFLIP:
                ctrl->value = priv->flag_hflip;
                break;
+       case V4L2_CID_BAND_STOP_FILTER:
+               ctrl->value = priv->band_filter;
+               break;
        }
        return 0;
 }
@@ -700,6 +713,29 @@ static int ov772x_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
                        val ^= HFLIP_IMG;
                ret = ov772x_mask_set(client, COM3, HFLIP_IMG, val);
                break;
+       case V4L2_CID_BAND_STOP_FILTER:
+               if ((unsigned)ctrl->value > 256)
+                       ctrl->value = 256;
+               if (ctrl->value == priv->band_filter)
+                       break;
+               if (!ctrl->value) {
+                       /* Switch the filter off, it is on now */
+                       ret = ov772x_mask_set(client, BDBASE, 0xff, 0xff);
+                       if (!ret)
+                               ret = ov772x_mask_set(client, COM8,
+                                                     BNDF_ON_OFF, 0);
+               } else {
+                       /* Switch the filter on, set AEC low limit */
+                       val = 256 - ctrl->value;
+                       ret = ov772x_mask_set(client, COM8,
+                                             BNDF_ON_OFF, BNDF_ON_OFF);
+                       if (!ret)
+                               ret = ov772x_mask_set(client, BDBASE,
+                                                     0xff, val);
+               }
+               if (!ret)
+                       priv->band_filter = ctrl->value;
+               break;
        }
 
        return ret;
@@ -893,6 +929,18 @@ static int ov772x_set_params(struct i2c_client *client,
        if (ret < 0)
                goto ov772x_set_fmt_error;
 
+       /*
+        * set COM8
+        */
+       if (priv->band_filter) {
+               ret = ov772x_mask_set(client, COM8, BNDF_ON_OFF, 1);
+               if (!ret)
+                       ret = ov772x_mask_set(client, BDBASE,
+                                             0xff, 256 - priv->band_filter);
+               if (ret < 0)
+                       goto ov772x_set_fmt_error;
+       }
+
        return ret;
 
 ov772x_set_fmt_error: