},
        [CX23885_BOARD_HAUPPAUGE_HVR1850] = {
                .name           = "Hauppauge WinTV-HVR1850",
+               .porta          = CX23885_ANALOG_VIDEO,
                .portb          = CX23885_MPEG_ENCODER,
                .portc          = CX23885_MPEG_DVB,
+               .tuner_type     = TUNER_ABSENT,
+               .tuner_addr     = 0x42, /* 0x84 >> 1 */
+               .force_bff      = 1,
+               .input          = {{
+                       .type   = CX23885_VMUX_TELEVISION,
+                       .vmux   =       CX25840_VIN7_CH3 |
+                                       CX25840_VIN5_CH2 |
+                                       CX25840_VIN2_CH1 |
+                                       CX25840_DIF_ON,
+                       .amux   = CX25840_AUDIO8,
+               }, {
+                       .type   = CX23885_VMUX_COMPOSITE1,
+                       .vmux   =       CX25840_VIN7_CH3 |
+                                       CX25840_VIN4_CH2 |
+                                       CX25840_VIN6_CH1,
+                       .amux   = CX25840_AUDIO7,
+               }, {
+                       .type   = CX23885_VMUX_SVIDEO,
+                       .vmux   =       CX25840_VIN7_CH3 |
+                                       CX25840_VIN4_CH2 |
+                                       CX25840_VIN8_CH1 |
+                                       CX25840_SVIDEO_ON,
+                       .amux   = CX25840_AUDIO7,
+               } },
        },
        [CX23885_BOARD_COMPRO_VIDEOMATE_E800] = {
                .name           = "Compro VideoMate E800",
                ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */
                ts1->src_sel_val   = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO;
                break;
+       case CX23885_BOARD_HAUPPAUGE_HVR1850:
        case CX23885_BOARD_HAUPPAUGE_HVR1800:
                /* Defaults for VID B - Analog encoder */
                /* DREQ_POL, SMODE, PUNC_CLK, MCLK_POL Serial bus + punc clk */
                /* APB_TSVALERR_POL (active low)*/
                ts1->vld_misc_val    = 0x2000;
                ts1->hw_sop_ctrl_val = (0x47 << 16 | 188 << 4 | 0xc);
+               cx_write(0x130184, 0xc);
 
                /* Defaults for VID C */
                ts2->gen_ctrl_val  = 0xc; /* Serial bus + punctured clock */
        case CX23885_BOARD_HAUPPAUGE_HVR1275:
        case CX23885_BOARD_HAUPPAUGE_HVR1255:
        case CX23885_BOARD_HAUPPAUGE_HVR1210:
-       case CX23885_BOARD_HAUPPAUGE_HVR1850:
        case CX23885_BOARD_COMPRO_VIDEOMATE_E800:
        case CX23885_BOARD_HAUPPAUGE_HVR1290:
        case CX23885_BOARD_GOTVIEW_X5_3D_HYBRID:
 
                        __func__, bc);
 }
 
-static int cx23885_set_tvnorm(struct cx23885_dev *dev, v4l2_std_id norm)
+int cx23885_set_tvnorm(struct cx23885_dev *dev, v4l2_std_id norm)
 {
        dprintk(1, "%s(norm = 0x%08x) name: [%s]\n",
                __func__,
                        INPUT(input)->vmux, 0, 0);
 
        if ((dev->board == CX23885_BOARD_HAUPPAUGE_HVR1800) ||
-               (dev->board == CX23885_BOARD_MPX885)) {
+               (dev->board == CX23885_BOARD_MPX885) ||
+               (dev->board == CX23885_BOARD_HAUPPAUGE_HVR1850)) {
                /* Configure audio routing */
                v4l2_subdev_call(dev->sd_cx25840, audio, s_routing,
                        INPUT(input)->amux, 0, 0);
        int rc, init_buffer = 0;
        u32 line0_offset, line1_offset;
        struct videobuf_dmabuf *dma = videobuf_to_dma(&buf->vb);
+       int field_tff;
 
        BUG_ON(NULL == fh->fmt);
        if (fh->width  < 48 || fh->width  > norm_maxw(dev->tvnorm) ||
                                         buf->bpl, 0, buf->vb.height);
                        break;
                case V4L2_FIELD_INTERLACED:
-                       if (dev->tvnorm & V4L2_STD_NTSC) {
+                       if (dev->tvnorm & V4L2_STD_NTSC)
+                               /* NTSC or  */
+                               field_tff = 1;
+                       else
+                               field_tff = 0;
+
+                       if (cx23885_boards[dev->board].force_bff)
+                               /* PAL / SECAM OR 888 in NTSC MODE */
+                               field_tff = 0;
+
+                       if (field_tff) {
                                /* cx25840 transmits NTSC bottom field first */
-                               dprintk(1, "%s() Creating NTSC risc\n",
+                               dprintk(1, "%s() Creating TFF/NTSC risc\n",
                                        __func__);
                                line0_offset = buf->bpl;
                                line1_offset = 0;
                        } else {
                                /* All other formats are top field first */
-                               dprintk(1, "%s() Creating PAL/SECAM risc\n",
+                               dprintk(1, "%s() Creating BFF/PAL/SECAM risc\n",
                                        __func__);
                                line0_offset = 0;
                                line1_offset = buf->bpl;
        }
 
        videobuf_mmap_free(&fh->vidq);
+       videobuf_mmap_free(&fh->vbiq);
+
        file->private_data = NULL;
        kfree(fh);
 
 /* ------------------------------------------------------------------ */
 /* VIDEO CTRL IOCTLS                                                  */
 
-static int cx23885_get_control(struct cx23885_dev *dev,
+int cx23885_get_control(struct cx23885_dev *dev,
        struct v4l2_control *ctl)
 {
        dprintk(1, "%s() calling cx25840(VIDIOC_G_CTRL)\n", __func__);
        return 0;
 }
 
-static int cx23885_set_control(struct cx23885_dev *dev,
+int cx23885_set_control(struct cx23885_dev *dev,
        struct v4l2_control *ctl)
 {
        dprintk(1, "%s() calling cx25840(VIDIOC_S_CTRL)\n", __func__);
        return 0;
 }
 
+static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *id)
+{
+       struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev;
+       dprintk(1, "%s()\n", __func__);
+
+       call_all(dev, core, g_std, id);
+
+       return 0;
+}
+
 static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *tvnorms)
 {
        struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev;
        return 0;
 }
 
-static int cx23885_enum_input(struct cx23885_dev *dev, struct v4l2_input *i)
+int cx23885_enum_input(struct cx23885_dev *dev, struct v4l2_input *i)
 {
        static const char *iname[] = {
                [CX23885_VMUX_COMPOSITE1] = "Composite1",
        return cx23885_enum_input(dev, i);
 }
 
-static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
+int cx23885_get_input(struct file *file, void *priv, unsigned int *i)
 {
        struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev;
 
        return 0;
 }
 
-static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
+static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
+{
+       return cx23885_get_input(file, priv, i);
+}
+
+int cx23885_set_input(struct file *file, void *priv, unsigned int i)
 {
        struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev;
 
        return 0;
 }
 
+static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
+{
+       return cx23885_set_input(file, priv, i);
+}
+
 static int vidioc_log_status(struct file *file, void *priv)
 {
        struct cx23885_fh  *fh  = priv;
 
        printk(KERN_INFO
                "%s/0: ============  START LOG STATUS  ============\n",
-              dev->name);
+               dev->name);
        call_all(dev, core, log_status);
        printk(KERN_INFO
                "%s/0: =============  END LOG STATUS  =============\n",
-              dev->name);
+               dev->name);
        return 0;
 }
 
 
 static int cx23885_set_freq(struct cx23885_dev *dev, struct v4l2_frequency *f)
 {
+       struct v4l2_control ctrl;
+
        if (unlikely(UNSET == dev->tuner_type))
                return -EINVAL;
        if (unlikely(f->tuner != 0))
        mutex_lock(&dev->lock);
        dev->freq = f->frequency;
 
+       /* I need to mute audio here */
+       ctrl.id = V4L2_CID_AUDIO_MUTE;
+       ctrl.value = 1;
+       cx23885_set_control(dev, &ctrl);
+
        call_all(dev, tuner, s_frequency, f);
 
        /* When changing channels it is required to reset TVAUDIO */
-       msleep(10);
+       msleep(100);
+
+       /* I need to unmute audio here */
+       ctrl.value = 0;
+       cx23885_set_control(dev, &ctrl);
 
        mutex_unlock(&dev->lock);
 
        return 0;
 }
 
-static int vidioc_s_frequency(struct file *file, void *priv,
-                               struct v4l2_frequency *f)
+static int cx23885_set_freq_via_ops(struct cx23885_dev *dev,
+       struct v4l2_frequency *f)
+{
+       struct v4l2_control ctrl;
+       struct videobuf_dvb_frontend *vfe;
+       struct dvb_frontend *fe;
+       int err = 0;
+
+       struct analog_parameters params = {
+               .mode      = V4L2_TUNER_ANALOG_TV,
+               .audmode   = V4L2_TUNER_MODE_STEREO,
+               .std       = dev->tvnorm,
+               .frequency = f->frequency
+       };
+
+       mutex_lock(&dev->lock);
+       dev->freq = f->frequency;
+
+       /* I need to mute audio here */
+       ctrl.id = V4L2_CID_AUDIO_MUTE;
+       ctrl.value = 1;
+       cx23885_set_control(dev, &ctrl);
+
+       /* If HVR1850 */
+       dprintk(1, "%s() frequency=%d tuner=%d std=0x%llx\n", __func__,
+               params.frequency, f->tuner, params.std);
+
+       vfe = videobuf_dvb_get_frontend(&dev->ts2.frontends, 1);
+       if (!vfe)
+               err = -EINVAL;
+
+       fe = vfe->dvb.frontend;
+
+       if (dev->board == CX23885_BOARD_HAUPPAUGE_HVR1850)
+               fe = &dev->ts1.analog_fe;
+
+       if (fe && fe->ops.tuner_ops.set_analog_params) {
+               call_all(dev, core, s_std, dev->tvnorm);
+               fe->ops.tuner_ops.set_analog_params(fe, ¶ms);
+       }
+       else
+               printk(KERN_ERR "%s() No analog tuner, aborting\n", __func__);
+
+       /* When changing channels it is required to reset TVAUDIO */
+       msleep(100);
+
+       /* I need to unmute audio here */
+       ctrl.value = 0;
+       cx23885_set_control(dev, &ctrl);
+
+       mutex_unlock(&dev->lock);
+
+       return 0;
+}
+
+int cx23885_set_frequency(struct file *file, void *priv,
+       struct v4l2_frequency *f)
 {
        struct cx23885_fh *fh = priv;
        struct cx23885_dev *dev = fh->dev;
+       int ret;
 
-       if (unlikely(0 == fh->radio && f->type != V4L2_TUNER_ANALOG_TV))
-               return -EINVAL;
-       if (unlikely(1 == fh->radio && f->type != V4L2_TUNER_RADIO))
-               return -EINVAL;
+       switch (dev->board) {
+       case CX23885_BOARD_HAUPPAUGE_HVR1850:
+               ret = cx23885_set_freq_via_ops(dev, f);
+               break;
+       default:
+               ret = cx23885_set_freq(dev, f);
+       }
 
-       return
-               cx23885_set_freq(dev, f);
+       return ret;
+}
+
+static int vidioc_s_frequency(struct file *file, void *priv,
+       struct v4l2_frequency *f)
+{
+       return cx23885_set_frequency(file, priv, f);
 }
 
 /* ----------------------------------------------------------- */
        .vidioc_qbuf          = vidioc_qbuf,
        .vidioc_dqbuf         = vidioc_dqbuf,
        .vidioc_s_std         = vidioc_s_std,
+       .vidioc_g_std         = vidioc_g_std,
+       .vidioc_querystd      = vidioc_g_std,
        .vidioc_enum_input    = vidioc_enum_input,
        .vidioc_g_input       = vidioc_g_input,
        .vidioc_s_input       = vidioc_s_input,