usb: quickcam_messenger free urb cleanup
[safe/jmp/linux-2.6] / drivers / media / video / tvp5150.c
index f7fa93c..bc0a4fc 100644 (file)
@@ -1,8 +1,8 @@
 /*
- * tvp5150 - Texas Instruments TVP5150A(M) video decoder driver
+ * tvp5150 - Texas Instruments TVP5150A/AM1 video decoder driver
  *
- * Copyright (c) 2005 Mauro Carvalho Chehab (mchehab@brturbo.com.br)
- * This code is placed under the terms of the GNU General Public License
+ * Copyright (c) 2005,2006 Mauro Carvalho Chehab (mchehab@infradead.org)
+ * This code is placed under the terms of the GNU General Public License v2
  */
 
 #include <linux/i2c.h>
 #include <linux/delay.h>
 #include <linux/video_decoder.h>
 #include <media/v4l2-common.h>
+#include <media/tvp5150.h>
 
 #include "tvp5150_reg.h"
 
-MODULE_DESCRIPTION("Texas Instruments TVP5150A video decoder driver"); /* standard i2c insmod options */
+MODULE_DESCRIPTION("Texas Instruments TVP5150A video decoder driver");
 MODULE_AUTHOR("Mauro Carvalho Chehab");
 MODULE_LICENSE("GPL");
 
+/* standard i2c insmod options */
 static unsigned short normal_i2c[] = {
        0xb8 >> 1,
        0xba >> 1,
@@ -52,7 +54,7 @@ static struct v4l2_queryctrl tvp5150_qctrl[] = {
                .minimum = 0,
                .maximum = 255,
                .step = 1,
-               .default_value = 0,
+               .default_value = 128,
                .flags = 0,
        }, {
                .id = V4L2_CID_CONTRAST,
@@ -61,7 +63,7 @@ static struct v4l2_queryctrl tvp5150_qctrl[] = {
                .minimum = 0,
                .maximum = 255,
                .step = 0x1,
-               .default_value = 0x10,
+               .default_value = 128,
                .flags = 0,
        }, {
                 .id = V4L2_CID_SATURATION,
@@ -70,7 +72,7 @@ static struct v4l2_queryctrl tvp5150_qctrl[] = {
                 .minimum = 0,
                 .maximum = 255,
                 .step = 0x1,
-                .default_value = 0x10,
+                .default_value = 128,
                 .flags = 0,
        }, {
                .id = V4L2_CID_HUE,
@@ -79,7 +81,7 @@ static struct v4l2_queryctrl tvp5150_qctrl[] = {
                .minimum = -128,
                .maximum = 127,
                .step = 0x1,
-               .default_value = 0x10,
+               .default_value = 0,
                .flags = 0,
        }
 };
@@ -88,7 +90,7 @@ struct tvp5150 {
        struct i2c_client *client;
 
        v4l2_std_id norm;       /* Current set standard */
-       int input;
+       struct v4l2_routing route;
        int enable;
        int bright;
        int contrast;
@@ -282,33 +284,35 @@ static void dump_reg(struct i2c_client *c)
 /****************************************************************************
                        Basic functions
  ****************************************************************************/
-enum tvp5150_input {
-       TVP5150_ANALOG_CH0 = 0,
-       TVP5150_SVIDEO = 1,
-       TVP5150_ANALOG_CH1 = 2,
-       TVP5150_BLACK_SCREEN = 8
-};
 
-static inline void tvp5150_selmux(struct i2c_client *c,
-                                 enum tvp5150_input input)
+static inline void tvp5150_selmux(struct i2c_client *c)
 {
        int opmode=0;
-
        struct tvp5150 *decoder = i2c_get_clientdata(c);
+       int input = 0;
 
-       if (!decoder->enable)
-               input |= TVP5150_BLACK_SCREEN;
+       if ((decoder->route.output & TVP5150_BLACK_SCREEN) || !decoder->enable)
+               input = 8;
 
-       switch (input) {
-       case TVP5150_ANALOG_CH0:
-       case TVP5150_ANALOG_CH1:
+       switch (decoder->route.input) {
+       case TVP5150_COMPOSITE1:
+               input |= 2;
+               /* fall through */
+       case TVP5150_COMPOSITE0:
                opmode=0x30;            /* TV Mode */
                break;
+       case TVP5150_SVIDEO:
        default:
+               input |= 1;
                opmode=0;               /* Auto Mode */
                break;
        }
 
+       tvp5150_dbg( 1, "Selecting video route: route input=%i, output=%i "
+                       "=> tvp5150 input=%i, opmode=%i\n",
+                       decoder->route.input,decoder->route.output,
+                       input, opmode );
+
        tvp5150_write(c, TVP5150_OP_MODE_CTL, opmode);
        tvp5150_write(c, TVP5150_VD_IN_SRC_SEL_1, input);
 };
@@ -477,82 +481,109 @@ static const struct i2c_reg_value tvp5150_init_enable[] = {
        }
 };
 
+struct tvp5150_vbi_type {
+       unsigned int vbi_type;
+       unsigned int ini_line;
+       unsigned int end_line;
+       unsigned int by_field :1;
+};
+
 struct i2c_vbi_ram_value {
        u16 reg;
-       unsigned char values[26];
+       struct tvp5150_vbi_type type;
+       unsigned char values[16];
 };
 
-/* tvp5150_vbi_types should follow the same order as vbi_ram_default
+/* This struct have the values for each supported VBI Standard
+ * by
+ tvp5150_vbi_types should follow the same order as vbi_ram_default
  * value 0 means rom position 0x10, value 1 means rom position 0x30
  * and so on. There are 16 possible locations from 0 to 15.
  */
-enum tvp5150_vbi_types {       /* Video line number  Description */
-       VBI_WST_SECAM,          /* 6-23  (field 1,2)  Teletext, SECAM */
-       VBI_WST_PAL_B,          /* 6-22  (field 1,2)  Teletext, PAL, System B */
-       VBI_WST_PAL_C,          /* 6-22  (field 1,2)  Teletext, PAL, System C */
-       VBI_WST_NTSC_B,         /* 10-21 (field 1,2)  Teletext, NTSC, System B */
-       VBI_NABTS_NTSC_C,       /* 10-21 (field 1,2)  Teletext, NTSC, System C */
-       VBI_NABTS_NTSC_D,       /* 10-21 (field 1,2)  Teletext, NTSC, System D */
-       VBI_CC_PAL_SECAM,       /* 22    (field 1,2)  Closed Caption PAL/SECAM */
-       VBI_CC_NTSC,            /* 21    (field 1,2)  Closed Caption NTSC */
-       VBI_WSS_PAL_SECAM,      /* 23    (field 1,2)  Wide Screen Signal PAL/SECAM */
-       VBI_WSS_NTSC,           /* 20    (field 1,2)  Wide Screen Signal NTSC */
-       VBI_VITC_PAL_SECAM,     /* 6-22               Vertical Interval Timecode PAL/SECAM */
-       VBI_VITC_NTSC,          /* 10-20              Vertical Interval Timecode NTSC */
-       VBI_VPS_PAL,            /* 16                 Video Program System PAL */
-       VBI_EPG_GEMSTAR,        /*                    EPG/Gemstar Electronic program guide */
-       VBI_RESERVED,           /*                    not in use on vbi_ram_default table */
-       VBI_FULL_FIELD          /*                    Active video/Full Field */
-};
 
 static struct i2c_vbi_ram_value vbi_ram_default[] =
 {
-       {0x010, /* WST SECAM */
-               { 0xaa, 0xaa, 0xff, 0xff , 0xe7, 0x2e, 0x20, 0x26, 0xe6, 0xb4, 0x0e, 0x0, 0x0, 0x0, 0x10, 0x0 }
-       },
-       {0x030, /* WST PAL B */
-               { 0xaa, 0xaa, 0xff, 0xff , 0x27, 0x2e, 0x20, 0x2b, 0xa6, 0x72, 0x10, 0x0, 0x0, 0x0, 0x10, 0x0 }
+       /* FIXME: Current api doesn't handle all VBI types, those not
+          yet supported are placed under #if 0 */
+#if 0
+       {0x010, /* Teletext, SECAM, WST System A */
+               {V4L2_SLICED_TELETEXT_SECAM,6,23,1},
+               { 0xaa, 0xaa, 0xff, 0xff, 0xe7, 0x2e, 0x20, 0x26,
+                 0xe6, 0xb4, 0x0e, 0x00, 0x00, 0x00, 0x10, 0x00 }
        },
-       {0x050, /* WST PAL C */
-               { 0xaa, 0xaa, 0xff, 0xff , 0xe7, 0x2e, 0x20, 0x22, 0xa6, 0x98, 0x0d, 0x0, 0x0, 0x0, 0x10, 0x0 }
+#endif
+       {0x030, /* Teletext, PAL, WST System B */
+               {V4L2_SLICED_TELETEXT_B,6,22,1},
+               { 0xaa, 0xaa, 0xff, 0xff, 0x27, 0x2e, 0x20, 0x2b,
+                 0xa6, 0x72, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00 }
        },
-       {0x070, /* WST NTSC B */
-               { 0xaa, 0xaa, 0xff, 0xff , 0x27, 0x2e, 0x20, 0x23, 0x69, 0x93, 0x0d, 0x0, 0x0, 0x0, 0x10, 0x0 }
+#if 0
+       {0x050, /* Teletext, PAL, WST System C */
+               {V4L2_SLICED_TELETEXT_PAL_C,6,22,1},
+               { 0xaa, 0xaa, 0xff, 0xff, 0xe7, 0x2e, 0x20, 0x22,
+                 0xa6, 0x98, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x00 }
        },
-       {0x090, /* NABTS, NTSC */
-               { 0xaa, 0xaa, 0xff, 0xff , 0xe7, 0x2e, 0x20, 0x22, 0x69, 0x93, 0x0d, 0x0, 0x0, 0x0, 0x15, 0x0 }
+       {0x070, /* Teletext, NTSC, WST System B */
+               {V4L2_SLICED_TELETEXT_NTSC_B,10,21,1},
+               { 0xaa, 0xaa, 0xff, 0xff, 0x27, 0x2e, 0x20, 0x23,
+                 0x69, 0x93, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x00 }
        },
-       {0x0b0, /* NABTS, NTSC-J */
-               { 0xaa, 0xaa, 0xff, 0xff , 0xa7, 0x2e, 0x20, 0x23, 0x69, 0x93, 0x0d, 0x0, 0x0, 0x0, 0x10, 0x0 }
+       {0x090, /* Tetetext, NTSC NABTS System C */
+               {V4L2_SLICED_TELETEXT_NTSC_C,10,21,1},
+               { 0xaa, 0xaa, 0xff, 0xff, 0xe7, 0x2e, 0x20, 0x22,
+                 0x69, 0x93, 0x0d, 0x00, 0x00, 0x00, 0x15, 0x00 }
        },
-       {0x0d0, /* CC, PAL/SECAM */
-               { 0xaa, 0x2a, 0xff, 0x3f , 0x04, 0x51, 0x6e, 0x02, 0xa6, 0x7b, 0x09, 0x0, 0x0, 0x0, 0x27, 0x0 }
+       {0x0b0, /* Teletext, NTSC-J, NABTS System D */
+               {V4L2_SLICED_TELETEXT_NTSC_D,10,21,1},
+               { 0xaa, 0xaa, 0xff, 0xff, 0xa7, 0x2e, 0x20, 0x23,
+                 0x69, 0x93, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x00 }
        },
-       {0x0f0, /* CC, NTSC */
-               { 0xaa, 0x2a, 0xff, 0x3f , 0x04, 0x51, 0x6e, 0x02, 0x69, 0x8c, 0x09, 0x0, 0x0, 0x0, 0x27, 0x0 }
+       {0x0d0, /* Closed Caption, PAL/SECAM */
+               {V4L2_SLICED_CAPTION_625,22,22,1},
+               { 0xaa, 0x2a, 0xff, 0x3f, 0x04, 0x51, 0x6e, 0x02,
+                 0xa6, 0x7b, 0x09, 0x00, 0x00, 0x00, 0x27, 0x00 }
        },
-       {0x110, /* WSS, PAL/SECAM */
-               { 0x5b, 0x55, 0xc5, 0xff , 0x0, 0x71, 0x6e, 0x42, 0xa6, 0xcd, 0x0f, 0x0, 0x0, 0x0, 0x3a, 0x0 }
+#endif
+       {0x0f0, /* Closed Caption, NTSC */
+               {V4L2_SLICED_CAPTION_525,21,21,1},
+               { 0xaa, 0x2a, 0xff, 0x3f, 0x04, 0x51, 0x6e, 0x02,
+                 0x69, 0x8c, 0x09, 0x00, 0x00, 0x00, 0x27, 0x00 }
        },
-       {0x130, /* WSS, NTSC C */
-               { 0x38, 0x00, 0x3f, 0x00 , 0x0, 0x71, 0x6e, 0x43, 0x69, 0x7c, 0x08, 0x0, 0x0, 0x0, 0x39, 0x0 }
+       {0x110, /* Wide Screen Signal, PAL/SECAM */
+               {V4L2_SLICED_WSS_625,23,23,1},
+               { 0x5b, 0x55, 0xc5, 0xff, 0x00, 0x71, 0x6e, 0x42,
+                 0xa6, 0xcd, 0x0f, 0x00, 0x00, 0x00, 0x3a, 0x00 }
        },
-       {0x150, /* VITC, PAL/SECAM */
-               { 0x0, 0x0, 0x0, 0x0 , 0x0, 0x8f, 0x6d, 0x49, 0xa6, 0x85, 0x08, 0x0, 0x0, 0x0, 0x4c, 0x0 }
+#if 0
+       {0x130, /* Wide Screen Signal, NTSC C */
+               {V4L2_SLICED_WSS_525,20,20,1},
+               { 0x38, 0x00, 0x3f, 0x00, 0x00, 0x71, 0x6e, 0x43,
+                 0x69, 0x7c, 0x08, 0x00, 0x00, 0x00, 0x39, 0x00 }
        },
-       {0x170, /* VITC, NTSC */
-               { 0x0, 0x0, 0x0, 0x0 , 0x0, 0x8f, 0x6d, 0x49, 0x69, 0x94, 0x08, 0x0, 0x0, 0x0, 0x4c, 0x0 }
+       {0x150, /* Vertical Interval Timecode (VITC), PAL/SECAM */
+               {V4l2_SLICED_VITC_625,6,22,0},
+               { 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, 0x6d, 0x49,
+                 0xa6, 0x85, 0x08, 0x00, 0x00, 0x00, 0x4c, 0x00 }
        },
-       {0x190, /* VPS, PAL */
-               { 0xaa, 0xaa, 0xff, 0xff, 0xba, 0xce, 0x2b, 0x0d, 0xa6, 0xda, 0x0b, 0x0, 0x0, 0x0, 0x60, 0x0 }
+       {0x170, /* Vertical Interval Timecode (VITC), NTSC */
+               {V4l2_SLICED_VITC_525,10,20,0},
+               { 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, 0x6d, 0x49,
+                 0x69, 0x94, 0x08, 0x00, 0x00, 0x00, 0x4c, 0x00 }
        },
-       {0x1b0, /* Gemstar Custom 1 */
-               { 0xcc, 0xcc, 0xff, 0xff, 0x05, 0x51, 0x6e, 0x05, 0x69, 0x19, 0x13, 0x0, 0x0, 0x0, 0x60, 0x0 }
+#endif
+       {0x190, /* Video Program System (VPS), PAL */
+               {V4L2_SLICED_VPS,16,16,0},
+               { 0xaa, 0xaa, 0xff, 0xff, 0xba, 0xce, 0x2b, 0x0d,
+                 0xa6, 0xda, 0x0b, 0x00, 0x00, 0x00, 0x60, 0x00 }
        },
+       /* 0x1d0 User programmable */
+
+       /* End of struct */
+       { (u16)-1 }
 };
 
 static int tvp5150_write_inittab(struct i2c_client *c,
-                                const struct i2c_reg_value *regs)
+                               const struct i2c_reg_value *regs)
 {
        while (regs->reg != 0xff) {
                tvp5150_write(c, regs->reg, regs->value);
@@ -562,7 +593,7 @@ static int tvp5150_write_inittab(struct i2c_client *c,
 }
 
 static int tvp5150_vdp_init(struct i2c_client *c,
-                                const struct i2c_vbi_ram_value *regs)
+                               const struct i2c_vbi_ram_value *regs)
 {
        unsigned int i;
 
@@ -586,6 +617,24 @@ static int tvp5150_vdp_init(struct i2c_client *c,
        return 0;
 }
 
+/* Fills VBI capabilities based on i2c_vbi_ram_value struct */
+static void tvp5150_vbi_get_cap(const struct i2c_vbi_ram_value *regs,
+                               struct v4l2_sliced_vbi_cap *cap)
+{
+       int line;
+
+       memset(cap, 0, sizeof *cap);
+
+       while (regs->reg != (u16)-1 ) {
+               for (line=regs->type.ini_line;line<=regs->type.end_line;line++) {
+                       cap->service_lines[0][line] |= regs->type.vbi_type;
+               }
+               cap->service_set |= regs->type.vbi_type;
+
+               regs++;
+       }
+}
+
 /* Set vbi processing
  * type - one of tvp5150_vbi_types
  * line - line to gather data
@@ -599,25 +648,42 @@ static int tvp5150_vdp_init(struct i2c_client *c,
  *     LSB = field1
  *     MSB = field2
  */
-static int tvp5150_set_vbi(struct i2c_client *c, enum tvp5150_vbi_types type,
-                                       u8 flags, int line, const int fields)
+static int tvp5150_set_vbi(struct i2c_client *c,
+                       const struct i2c_vbi_ram_value *regs,
+                       unsigned int type,u8 flags, int line,
+                       const int fields)
 {
        struct tvp5150 *decoder = i2c_get_clientdata(c);
        v4l2_std_id std=decoder->norm;
        u8 reg;
+       int pos=0;
 
        if (std == V4L2_STD_ALL) {
                tvp5150_err("VBI can't be configured without knowing number of lines\n");
-               return -EINVAL;
+               return 0;
        } else if (std && V4L2_STD_625_50) {
                /* Don't follow NTSC Line number convension */
                line += 3;
        }
 
        if (line<6||line>27)
-               return -EINVAL;
+               return 0;
+
+       while (regs->reg != (u16)-1 ) {
+               if ((type & regs->type.vbi_type) &&
+                   (line>=regs->type.ini_line) &&
+                   (line<=regs->type.end_line)) {
+                       type=regs->type.vbi_type;
+                       break;
+               }
 
-       type=type | (flags & 0xf0);
+               regs++;
+               pos++;
+       }
+       if (regs->reg == (u16)-1)
+               return 0;
+
+       type=pos | (flags & 0xf0);
        reg=((line-6)<<1)+TVP5150_LINE_MODE_INI;
 
        if (fields&1) {
@@ -628,9 +694,40 @@ static int tvp5150_set_vbi(struct i2c_client *c, enum tvp5150_vbi_types type,
                tvp5150_write(c, reg+1, type);
        }
 
-       return 0;
+       return type;
 }
 
+static int tvp5150_get_vbi(struct i2c_client *c,
+                       const struct i2c_vbi_ram_value *regs, int line)
+{
+       struct tvp5150 *decoder = i2c_get_clientdata(c);
+       v4l2_std_id std=decoder->norm;
+       u8 reg;
+       int pos, type=0;
+
+       if (std == V4L2_STD_ALL) {
+               tvp5150_err("VBI can't be configured without knowing number of lines\n");
+               return 0;
+       } else if (std && V4L2_STD_625_50) {
+               /* Don't follow NTSC Line number convension */
+               line += 3;
+       }
+
+       if (line<6||line>27)
+               return 0;
+
+       reg=((line-6)<<1)+TVP5150_LINE_MODE_INI;
+
+       pos=tvp5150_read(c, reg)&0x0f;
+       if (pos<0x0f)
+               type=regs[pos].type.vbi_type;
+
+       pos=tvp5150_read(c, reg+1)&0x0f;
+       if (pos<0x0f)
+               type|=regs[pos].type.vbi_type;
+
+       return type;
+}
 static int tvp5150_set_std(struct i2c_client *c, v4l2_std_id std)
 {
        struct tvp5150 *decoder = i2c_get_clientdata(c);
@@ -696,7 +793,7 @@ static inline void tvp5150_reset(struct i2c_client *c)
        tvp5150_vdp_init(c, vbi_ram_default);
 
        /* Selects decoder input */
-       tvp5150_selmux(c, decoder->input);
+       tvp5150_selmux(c);
 
        /* Initializes TVP5150 to stream enabled values */
        tvp5150_write_inittab(c, tvp5150_init_enable);
@@ -764,9 +861,23 @@ static int tvp5150_command(struct i2c_client *c,
 
        case 0:
        case VIDIOC_INT_RESET:
-       case DECODER_INIT:
                tvp5150_reset(c);
                break;
+       case VIDIOC_INT_G_VIDEO_ROUTING:
+       {
+               struct v4l2_routing *route = arg;
+
+               *route = decoder->route;
+               break;
+       }
+       case VIDIOC_INT_S_VIDEO_ROUTING:
+       {
+               struct v4l2_routing *route = arg;
+
+               decoder->route = *route;
+               tvp5150_selmux(c);
+               break;
+       }
        case VIDIOC_S_STD:
                if (decoder->norm == *(v4l2_std_id *)arg)
                        break;
@@ -775,6 +886,69 @@ static int tvp5150_command(struct i2c_client *c,
                *(v4l2_std_id *)arg = decoder->norm;
                break;
 
+       case VIDIOC_G_SLICED_VBI_CAP:
+       {
+               struct v4l2_sliced_vbi_cap *cap = arg;
+               tvp5150_dbg(1, "VIDIOC_G_SLICED_VBI_CAP\n");
+
+               tvp5150_vbi_get_cap(vbi_ram_default, cap);
+               break;
+       }
+       case VIDIOC_S_FMT:
+       {
+               struct v4l2_format *fmt;
+               struct v4l2_sliced_vbi_format *svbi;
+               int i;
+
+               fmt = arg;
+               if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
+                       return -EINVAL;
+               svbi = &fmt->fmt.sliced;
+               if (svbi->service_set != 0) {
+                       for (i = 0; i <= 23; i++) {
+                               svbi->service_lines[1][i] = 0;
+
+                               svbi->service_lines[0][i]=tvp5150_set_vbi(c,
+                                        vbi_ram_default,
+                                        svbi->service_lines[0][i],0xf0,i,3);
+                       }
+                       /* Enables FIFO */
+                       tvp5150_write(c, TVP5150_FIFO_OUT_CTRL,1);
+               } else {
+                       /* Disables FIFO*/
+                       tvp5150_write(c, TVP5150_FIFO_OUT_CTRL,0);
+
+                       /* Disable Full Field */
+                       tvp5150_write(c, TVP5150_FULL_FIELD_ENA, 0);
+
+                       /* Disable Line modes */
+                       for (i=TVP5150_LINE_MODE_INI; i<=TVP5150_LINE_MODE_END; i++)
+                               tvp5150_write(c, i, 0xff);
+               }
+               break;
+       }
+       case VIDIOC_G_FMT:
+       {
+               struct v4l2_format *fmt;
+               struct v4l2_sliced_vbi_format *svbi;
+
+               int i, mask=0;
+
+               fmt = arg;
+               if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
+                       return -EINVAL;
+               svbi = &fmt->fmt.sliced;
+               memset(svbi, 0, sizeof(*svbi));
+
+               for (i = 0; i <= 23; i++) {
+                       svbi->service_lines[0][i]=tvp5150_get_vbi(c,
+                               vbi_ram_default,i);
+                       mask|=svbi->service_lines[0][i];
+               }
+               svbi->service_set=mask;
+               break;
+       }
+
 #ifdef CONFIG_VIDEO_ADV_DEBUG
        case VIDIOC_INT_G_REGISTER:
        {
@@ -799,88 +973,16 @@ static int tvp5150_command(struct i2c_client *c,
        }
 #endif
 
-       case DECODER_DUMP:
+       case VIDIOC_LOG_STATUS:
                dump_reg(c);
                break;
 
-       case DECODER_GET_CAPABILITIES:
-               {
-                       struct video_decoder_capability *cap = arg;
-
-                       cap->flags = VIDEO_DECODER_PAL |
-                           VIDEO_DECODER_NTSC |
-                           VIDEO_DECODER_SECAM |
-                           VIDEO_DECODER_AUTO | VIDEO_DECODER_CCIR;
-                       cap->inputs = 3;
-                       cap->outputs = 1;
-                       break;
-               }
-       case DECODER_GET_STATUS:
+       case VIDIOC_G_TUNER:
                {
-                       break;
-               }
-
-       case DECODER_SET_GPIO:
-               break;
-
-       case DECODER_SET_VBI_BYPASS:
-               break;
-
-       case DECODER_SET_NORM:
-               {
-                       int *iarg = arg;
-
-                       switch (*iarg) {
-
-                       case VIDEO_MODE_NTSC:
-                               break;
-
-                       case VIDEO_MODE_PAL:
-                               break;
-
-                       case VIDEO_MODE_SECAM:
-                               break;
-
-                       case VIDEO_MODE_AUTO:
-                               break;
-
-                       default:
-                               return -EINVAL;
-
-                       }
-                       decoder->norm = *iarg;
-                       break;
-               }
-       case DECODER_SET_INPUT:
-               {
-                       int *iarg = arg;
-                       if (*iarg < 0 || *iarg > 3) {
-                               return -EINVAL;
-                       }
-
-                       decoder->input = *iarg;
-                       tvp5150_selmux(c, decoder->input);
-
-                       break;
-               }
-       case DECODER_SET_OUTPUT:
-               {
-                       int *iarg = arg;
-
-                       /* not much choice of outputs */
-                       if (*iarg != 0) {
-                               return -EINVAL;
-                       }
-                       break;
-               }
-       case DECODER_ENABLE_OUTPUT:
-               {
-                       int *iarg = arg;
-
-                       decoder->enable = (*iarg != 0);
-
-                       tvp5150_selmux(c, decoder->input);
+                       struct v4l2_tuner *vt = arg;
+                       int status = tvp5150_read(c, 0x88);
 
+                       vt->signal = ((status & 0x04) && (status & 0x02)) ? 0xffff : 0x0;
                        break;
                }
        case VIDIOC_QUERYCTRL:
@@ -926,35 +1028,6 @@ static int tvp5150_command(struct i2c_client *c,
                        return -EINVAL;
                }
 
-       case DECODER_SET_PICTURE:
-               {
-                       struct video_picture *pic = arg;
-                       if (decoder->bright != pic->brightness) {
-                               /* We want 0 to 255 we get 0-65535 */
-                               decoder->bright = pic->brightness;
-                               tvp5150_write(c, TVP5150_BRIGHT_CTL,
-                                             decoder->bright >> 8);
-                       }
-                       if (decoder->contrast != pic->contrast) {
-                               /* We want 0 to 255 we get 0-65535 */
-                               decoder->contrast = pic->contrast;
-                               tvp5150_write(c, TVP5150_CONTRAST_CTL,
-                                             decoder->contrast >> 8);
-                       }
-                       if (decoder->sat != pic->colour) {
-                               /* We want 0 to 255 we get 0-65535 */
-                               decoder->sat = pic->colour;
-                               tvp5150_write(c, TVP5150_SATURATION_CTL,
-                                             decoder->contrast >> 8);
-                       }
-                       if (decoder->hue != pic->hue) {
-                               /* We want -128 to 127 we get 0-65535 */
-                               decoder->hue = pic->hue;
-                               tvp5150_write(c, TVP5150_HUE_CTL,
-                                             (decoder->hue - 32768) >> 8);
-                       }
-                       break;
-               }
        default:
                return -EINVAL;
        }
@@ -1008,7 +1081,7 @@ static int tvp5150_detect_client(struct i2c_adapter *adapter,
        rv = i2c_attach_client(c);
 
        core->norm = V4L2_STD_ALL;      /* Default is autodetect */
-       core->input = 2;
+       core->route.input = TVP5150_COMPOSITE1;
        core->enable = 1;
        core->bright = 32768;
        core->contrast = 32768;