Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
[pandora-kernel.git] / drivers / media / video / saa7115.c
index c0a7f8a..53b6fcd 100644 (file)
@@ -74,6 +74,7 @@ struct saa711x_state {
        int contrast;
        int hue;
        int sat;
+       int chroma_agc;
        int width;
        int height;
        u32 ident;
@@ -592,7 +593,7 @@ static const unsigned char saa7115_init_misc[] = {
        R_5D_DID, 0xbd,
        R_5E_SDID, 0x35,
 
-       R_02_INPUT_CNTL_1, 0x84,                /* input tuner -> input 4, amplifier active */
+       R_02_INPUT_CNTL_1, 0xc4, /* input tuner -> input 4, amplifier active */
 
        R_80_GLOBAL_CNTL_1, 0x20,               /* enable task B */
        R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0,
@@ -743,6 +744,7 @@ static int saa711x_s_clock_freq(struct v4l2_subdev *sd, u32 freq)
 static int saa711x_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
 {
        struct saa711x_state *state = to_state(sd);
+       u8 val;
 
        switch (ctrl->id) {
        case V4L2_CID_BRIGHTNESS:
@@ -784,7 +786,21 @@ static int saa711x_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
                state->hue = ctrl->value;
                saa711x_write(sd, R_0D_CHROMA_HUE_CNTL, state->hue);
                break;
-
+       case V4L2_CID_CHROMA_AGC:
+               val = saa711x_read(sd, R_0F_CHROMA_GAIN_CNTL);
+               state->chroma_agc = ctrl->value;
+               if (ctrl->value)
+                       val &= 0x7f;
+               else
+                       val |= 0x80;
+               saa711x_write(sd, R_0F_CHROMA_GAIN_CNTL, val);
+               break;
+       case V4L2_CID_CHROMA_GAIN:
+               /* Chroma gain cannot be set when AGC is enabled */
+               if (state->chroma_agc == 1)
+                       return -EINVAL;
+               saa711x_write(sd, R_0F_CHROMA_GAIN_CNTL, ctrl->value | 0x80);
+               break;
        default:
                return -EINVAL;
        }
@@ -809,6 +825,12 @@ static int saa711x_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
        case V4L2_CID_HUE:
                ctrl->value = state->hue;
                break;
+       case V4L2_CID_CHROMA_AGC:
+               ctrl->value = state->chroma_agc;
+               break;
+       case V4L2_CID_CHROMA_GAIN:
+               ctrl->value = saa711x_read(sd, R_0F_CHROMA_GAIN_CNTL) & 0x7f;
+               break;
        default:
                return -EINVAL;
        }
@@ -1069,7 +1091,7 @@ static void saa711x_set_lcr(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_forma
                                saa7115_cfg_vbi_off);
 }
 
-static int saa711x_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
+static int saa711x_g_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_format *sliced)
 {
        static u16 lcr2vbi[] = {
                0, V4L2_SLICED_TELETEXT_B, 0,   /* 1 */
@@ -1078,11 +1100,8 @@ static int saa711x_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
                V4L2_SLICED_VPS, 0, 0, 0, 0,    /* 7 */
                0, 0, 0, 0
        };
-       struct v4l2_sliced_vbi_format *sliced = &fmt->fmt.sliced;
        int i;
 
-       if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
-               return -EINVAL;
        memset(sliced, 0, sizeof(*sliced));
        /* done if using raw VBI */
        if (saa711x_read(sd, R_80_GLOBAL_CNTL_1) & 0x10)
@@ -1098,16 +1117,27 @@ static int saa711x_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
        return 0;
 }
 
+static int saa711x_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
+{
+       if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
+               return -EINVAL;
+       return saa711x_g_sliced_fmt(sd, &fmt->fmt.sliced);
+}
+
+static int saa711x_s_raw_fmt(struct v4l2_subdev *sd, struct v4l2_vbi_format *fmt)
+{
+       saa711x_set_lcr(sd, NULL);
+       return 0;
+}
+
+static int saa711x_s_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_format *fmt)
+{
+       saa711x_set_lcr(sd, fmt);
+       return 0;
+}
+
 static int saa711x_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
 {
-       if (fmt->type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) {
-               saa711x_set_lcr(sd, &fmt->fmt.sliced);
-               return 0;
-       }
-       if (fmt->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
-               saa711x_set_lcr(sd, NULL);
-               return 0;
-       }
        if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
                return -EINVAL;
 
@@ -1209,6 +1239,10 @@ static int saa711x_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
                return v4l2_ctrl_query_fill(qc, 0, 127, 1, 64);
        case V4L2_CID_HUE:
                return v4l2_ctrl_query_fill(qc, -128, 127, 1, 0);
+       case V4L2_CID_CHROMA_AGC:
+               return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);
+       case V4L2_CID_CHROMA_GAIN:
+               return v4l2_ctrl_query_fill(qc, 0, 127, 1, 48);
        default:
                return -EINVAL;
        }
@@ -1524,18 +1558,25 @@ static const struct v4l2_subdev_video_ops saa711x_video_ops = {
        .s_crystal_freq = saa711x_s_crystal_freq,
        .g_fmt = saa711x_g_fmt,
        .s_fmt = saa711x_s_fmt,
-       .g_vbi_data = saa711x_g_vbi_data,
-       .decode_vbi_line = saa711x_decode_vbi_line,
        .s_stream = saa711x_s_stream,
        .querystd = saa711x_querystd,
        .g_input_status = saa711x_g_input_status,
 };
 
+static const struct v4l2_subdev_vbi_ops saa711x_vbi_ops = {
+       .g_vbi_data = saa711x_g_vbi_data,
+       .decode_vbi_line = saa711x_decode_vbi_line,
+       .g_sliced_fmt = saa711x_g_sliced_fmt,
+       .s_sliced_fmt = saa711x_s_sliced_fmt,
+       .s_raw_fmt = saa711x_s_raw_fmt,
+};
+
 static const struct v4l2_subdev_ops saa711x_ops = {
        .core = &saa711x_core_ops,
        .tuner = &saa711x_tuner_ops,
        .audio = &saa711x_audio_ops,
        .video = &saa711x_video_ops,
+       .vbi = &saa711x_vbi_ops,
 };
 
 /* ----------------------------------------------------------------------- */
@@ -1593,6 +1634,7 @@ static int saa711x_probe(struct i2c_client *client,
        state->contrast = 64;
        state->hue = 0;
        state->sat = 64;
+       state->chroma_agc = 1;
        switch (chip_id) {
        case '1':
                state->ident = V4L2_IDENT_SAA7111;