The patch number 9993 was added via Jean-Francois Moine <[email protected]>
to http://linuxtv.org/hg/v4l-dvb master development tree.

Kernel patches in this development tree may be modified to be backward
compatible with older kernels. Compatibility modifications will be
removed before inclusion into the mainstream Kernel

If anyone has any objections, please let us know by sending a message to:
        [email protected]

------

merge:v4l-dvb


---

 linux/drivers/media/dvb/dvb-usb/gp8psk-fe.c     |  146 ++++++++++++----
 linux/drivers/media/dvb/dvb-usb/gp8psk.c        |    2 
 linux/drivers/media/dvb/dvb-usb/gp8psk.h        |    1 
 linux/drivers/media/video/em28xx/em28xx-core.c  |   19 +-
 linux/drivers/media/video/em28xx/em28xx-video.c |   75 ++++++--
 linux/drivers/media/video/em28xx/em28xx.h       |    7 
 linux/drivers/media/video/tuner-core.c          |    9 
 7 files changed, 202 insertions(+), 57 deletions(-)

diff -r 66b4f7c10719 -r 005567806273 linux/drivers/media/dvb/dvb-usb/gp8psk-fe.c
--- a/linux/drivers/media/dvb/dvb-usb/gp8psk-fe.c       Sat Dec 20 18:30:58 
2008 +0100
+++ b/linux/drivers/media/dvb/dvb-usb/gp8psk-fe.c       Sat Dec 20 18:32:30 
2008 +0100
@@ -25,6 +25,20 @@ struct gp8psk_fe_state {
        unsigned long status_check_interval;
 };
 
+static int gp8psk_tuned_to_DCII(struct dvb_frontend *fe)
+{
+       struct gp8psk_fe_state *st = fe->demodulator_priv;
+       u8 status;
+       gp8psk_usb_in_op(st->d, GET_8PSK_CONFIG, 0, 0, &status, 1);
+       return status & bmDCtuned;
+}
+
+static int gp8psk_set_tuner_mode(struct dvb_frontend *fe, int mode)
+{
+       struct gp8psk_fe_state *state = fe->demodulator_priv;
+       return gp8psk_usb_out_op(state->d, SET_8PSK_CONFIG, mode, 0, NULL, 0);
+}
+
 static int gp8psk_fe_update_status(struct gp8psk_fe_state *st)
 {
        u8 buf[6];
@@ -99,39 +113,114 @@ static int gp8psk_fe_get_tune_settings(s
        return 0;
 }
 
+static int gp8psk_fe_set_property(struct dvb_frontend *fe,
+       struct dtv_property *tvp)
+{
+       deb_fe("%s(..)\n", __func__);
+       return 0;
+}
+
+static int gp8psk_fe_get_property(struct dvb_frontend *fe,
+       struct dtv_property *tvp)
+{
+       deb_fe("%s(..)\n", __func__);
+       return 0;
+}
+
+
 static int gp8psk_fe_set_frontend(struct dvb_frontend* fe,
                                  struct dvb_frontend_parameters *fep)
 {
        struct gp8psk_fe_state *state = fe->demodulator_priv;
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
        u8 cmd[10];
        u32 freq = fep->frequency * 1000;
+       int gp_product_id = le16_to_cpu(state->d->udev->descriptor.idProduct);
+
+       deb_fe("%s()\n", __func__);
 
        cmd[4] = freq         & 0xff;
        cmd[5] = (freq >> 8)  & 0xff;
        cmd[6] = (freq >> 16) & 0xff;
        cmd[7] = (freq >> 24) & 0xff;
 
-       switch(fe->ops.info.type) {
-       case FE_QPSK:
-               cmd[0] =  fep->u.qpsk.symbol_rate        & 0xff;
-               cmd[1] = (fep->u.qpsk.symbol_rate >>  8) & 0xff;
-               cmd[2] = (fep->u.qpsk.symbol_rate >> 16) & 0xff;
-               cmd[3] = (fep->u.qpsk.symbol_rate >> 24) & 0xff;
+       switch (c->delivery_system) {
+       case SYS_DVBS:
+               /* Only QPSK is supported for DVB-S */
+               if (c->modulation != QPSK) {
+                       deb_fe("%s: unsupported modulation selected (%d)\n",
+                               __func__, c->modulation);
+                       return -EOPNOTSUPP;
+               }
+               c->fec_inner = FEC_AUTO;
+               break;
+       case SYS_DVBS2:
+               deb_fe("%s: DVB-S2 delivery system selected\n", __func__);
+               break;
+
+       default:
+               deb_fe("%s: unsupported delivery system selected (%d)\n",
+                       __func__, c->delivery_system);
+               return -EOPNOTSUPP;
+       }
+
+       cmd[0] =  c->symbol_rate        & 0xff;
+       cmd[1] = (c->symbol_rate >>  8) & 0xff;
+       cmd[2] = (c->symbol_rate >> 16) & 0xff;
+       cmd[3] = (c->symbol_rate >> 24) & 0xff;
+       switch (c->modulation) {
+       case QPSK:
+               if (gp_product_id == USB_PID_GENPIX_8PSK_REV_1_WARM)
+                       if (gp8psk_tuned_to_DCII(fe))
+                               gp8psk_bcm4500_reload(state->d);
+               switch (c->fec_inner) {
+               case FEC_1_2:
+                       cmd[9] = 0; break;
+               case FEC_2_3:
+                       cmd[9] = 1; break;
+               case FEC_3_4:
+                       cmd[9] = 2; break;
+               case FEC_5_6:
+                       cmd[9] = 3; break;
+               case FEC_7_8:
+                       cmd[9] = 4; break;
+               case FEC_AUTO:
+                       cmd[9] = 5; break;
+               default:
+                       cmd[9] = 5; break;
+               }
                cmd[8] = ADV_MOD_DVB_QPSK;
-               cmd[9] = 0x03; /*ADV_MOD_FEC_XXX*/
-               break;
-       default:
-               // other modes are unsuported right now
-               cmd[0] = 0;
-               cmd[1] = 0;
-               cmd[2] = 0;
-               cmd[3] = 0;
-               cmd[8] = 0;
+               break;
+       case PSK_8: /* PSK_8 is for compatibility with DN */
+               cmd[8] = ADV_MOD_TURBO_8PSK;
+               switch (c->fec_inner) {
+               case FEC_2_3:
+                       cmd[9] = 0; break;
+               case FEC_3_4:
+                       cmd[9] = 1; break;
+               case FEC_3_5:
+                       cmd[9] = 2; break;
+               case FEC_5_6:
+                       cmd[9] = 3; break;
+               case FEC_8_9:
+                       cmd[9] = 4; break;
+               default:
+                       cmd[9] = 0; break;
+               }
+               break;
+       case QAM_16: /* QAM_16 is for compatibility with DN */
+               cmd[8] = ADV_MOD_TURBO_16QAM;
                cmd[9] = 0;
                break;
-       }
-
-       gp8psk_usb_out_op(state->d,TUNE_8PSK,0,0,cmd,10);
+       default: /* Unknown modulation */
+               deb_fe("%s: unsupported modulation selected (%d)\n",
+                       __func__, c->modulation);
+               return -EOPNOTSUPP;
+       }
+
+       if (gp_product_id == USB_PID_GENPIX_8PSK_REV_1_WARM)
+               gp8psk_set_tuner_mode(fe, 0);
+       gp8psk_usb_out_op(state->d, TUNE_8PSK, 0, 0, cmd, 10);
 
        state->lock = 0;
        state->next_status_check = jiffies;
@@ -139,13 +228,6 @@ static int gp8psk_fe_set_frontend(struct
 
        return 0;
 }
-
-static int gp8psk_fe_get_frontend(struct dvb_frontend* fe,
-                                 struct dvb_frontend_parameters *fep)
-{
-       return 0;
-}
-
 
 static int gp8psk_fe_send_diseqc_msg (struct dvb_frontend* fe,
                                    struct dvb_diseqc_master_cmd *m)
@@ -261,9 +343,13 @@ static struct dvb_frontend_ops gp8psk_fe
                .symbol_rate_max        = 45000000,
                .symbol_rate_tolerance  = 500,  /* ppm */
                .caps = FE_CAN_INVERSION_AUTO |
-                               FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | 
FE_CAN_FEC_3_4 |
-                               FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | 
FE_CAN_FEC_AUTO |
-                               FE_CAN_QPSK
+                       FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
+                       FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
+                       /*
+                        * FE_CAN_QAM_16 is for compatibility
+                        * (Myth incorrectly detects Turbo-QPSK as plain QAM-16)
+                        */
+                       FE_CAN_QPSK | FE_CAN_QAM_16
        },
 
        .release = gp8psk_fe_release,
@@ -271,8 +357,10 @@ static struct dvb_frontend_ops gp8psk_fe
        .init = NULL,
        .sleep = NULL,
 
+       .set_property = gp8psk_fe_set_property,
+       .get_property = gp8psk_fe_get_property,
        .set_frontend = gp8psk_fe_set_frontend,
-       .get_frontend = gp8psk_fe_get_frontend,
+
        .get_tune_settings = gp8psk_fe_get_tune_settings,
 
        .read_status = gp8psk_fe_read_status,
diff -r 66b4f7c10719 -r 005567806273 linux/drivers/media/dvb/dvb-usb/gp8psk.c
--- a/linux/drivers/media/dvb/dvb-usb/gp8psk.c  Sat Dec 20 18:30:58 2008 +0100
+++ b/linux/drivers/media/dvb/dvb-usb/gp8psk.c  Sat Dec 20 18:32:30 2008 +0100
@@ -174,7 +174,6 @@ static int gp8psk_power_ctrl(struct dvb_
        return 0;
 }
 
-#if 0
 int gp8psk_bcm4500_reload(struct dvb_usb_device *d)
 {
        u8 buf;
@@ -191,7 +190,6 @@ int gp8psk_bcm4500_reload(struct dvb_usb
                        return EINVAL;
        return 0;
 }
-#endif  /*  0  */
 
 static int gp8psk_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
 {
diff -r 66b4f7c10719 -r 005567806273 linux/drivers/media/dvb/dvb-usb/gp8psk.h
--- a/linux/drivers/media/dvb/dvb-usb/gp8psk.h  Sat Dec 20 18:30:58 2008 +0100
+++ b/linux/drivers/media/dvb/dvb-usb/gp8psk.h  Sat Dec 20 18:32:30 2008 +0100
@@ -92,5 +92,6 @@ extern int gp8psk_usb_in_op(struct dvb_u
 extern int gp8psk_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 
index, u8 *b, int blen);
 extern int gp8psk_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value,
                             u16 index, u8 *b, int blen);
+extern int gp8psk_bcm4500_reload(struct dvb_usb_device *d);
 
 #endif
diff -r 66b4f7c10719 -r 005567806273 
linux/drivers/media/video/em28xx/em28xx-core.c
--- a/linux/drivers/media/video/em28xx/em28xx-core.c    Sat Dec 20 18:30:58 
2008 +0100
+++ b/linux/drivers/media/video/em28xx/em28xx-core.c    Sat Dec 20 18:32:30 
2008 +0100
@@ -621,10 +621,19 @@ int em28xx_capture_start(struct em28xx *
        return rc;
 }
 
-int em28xx_outfmt_set_yuv422(struct em28xx *dev)
-{
-       em28xx_write_reg(dev, EM28XX_R27_OUTFMT, 0x34);
-       em28xx_write_reg(dev, EM28XX_R10_VINMODE, 0x10);
+int em28xx_set_outfmt(struct em28xx *dev)
+{
+       int ret;
+
+       ret = em28xx_write_reg_bits(dev, EM28XX_R27_OUTFMT,
+                                   dev->format->reg | 0x20, 0x3f);
+       if (ret < 0)
+               return ret;
+
+       ret = em28xx_write_reg(dev, EM28XX_R10_VINMODE, 0x10);
+       if (ret < 0)
+               return ret;
+
        return em28xx_write_reg(dev, EM28XX_R11_VINCTRL, 0x11);
 }
 
@@ -686,7 +695,7 @@ int em28xx_resolution_set(struct em28xx 
        width = norm_maxw(dev);
        height = norm_maxh(dev) >> 1;
 
-       em28xx_outfmt_set_yuv422(dev);
+       em28xx_set_outfmt(dev);
        em28xx_accumulator_set(dev, 1, (width - 4) >> 2, 1, (height - 4) >> 2);
        em28xx_capture_area_set(dev, 0, 0, width >> 2, height >> 2);
        return em28xx_scaler_set(dev, dev->hscale, dev->vscale);
diff -r 66b4f7c10719 -r 005567806273 
linux/drivers/media/video/em28xx/em28xx-video.c
--- a/linux/drivers/media/video/em28xx/em28xx-video.c   Sat Dec 20 18:30:58 
2008 +0100
+++ b/linux/drivers/media/video/em28xx/em28xx-video.c   Sat Dec 20 18:32:30 
2008 +0100
@@ -95,6 +95,16 @@ MODULE_PARM_DESC(video_debug, "enable de
 
 /* Bitmask marking allocated devices from 0 to EM28XX_MAXBOARDS */
 static unsigned long em28xx_devused;
+
+/* supported video standards */
+static struct em28xx_fmt format[] = {
+       {
+               .name     = "16bpp YUY2, 4:2:2, packed",
+               .fourcc   = V4L2_PIX_FMT_YUYV,
+               .depth    = 16,
+               .reg      = 0x14,
+       },
+};
 
 /* supported controls */
 /* Common to all boards */
@@ -390,16 +400,18 @@ buffer_setup(struct videobuf_queue *vq, 
        struct em28xx        *dev = fh->dev;
        struct v4l2_frequency f;
 
-       *size = 16 * fh->dev->width * fh->dev->height >> 3;
+       *size = (fh->dev->width * fh->dev->height * dev->format->depth + 7) >> 
3;
+
        if (0 == *count)
                *count = EM28XX_DEF_BUF;
 
        if (*count < EM28XX_MIN_BUF)
                *count = EM28XX_MIN_BUF;
 
-       /* Ask tuner to go to analog mode */
+       /* Ask tuner to go to analog or radio mode */
        memset(&f, 0, sizeof(f));
        f.frequency = dev->ctl_freq;
+       f.type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
 
        em28xx_i2c_call_clients(dev, VIDIOC_S_FREQUENCY, &f);
 
@@ -442,9 +454,7 @@ buffer_prepare(struct videobuf_queue *vq
        struct em28xx        *dev = fh->dev;
        int                  rc = 0, urb_init = 0;
 
-       /* FIXME: It assumes depth = 16 */
-       /* The only currently supported format is 16 bits/pixel */
-       buf->vb.size = 16 * dev->width * dev->height >> 3;
+       buf->vb.size = (fh->dev->width * fh->dev->height * dev->format->depth + 
7) >> 3;
 
        if (0 != buf->vb.baddr  &&  buf->vb.bsize < buf->vb.size)
                return -EINVAL;
@@ -541,7 +551,7 @@ static int em28xx_config(struct em28xx *
        dev->mute = 1;          /* maybe not the right place... */
        dev->volume = 0x1f;
 
-       em28xx_outfmt_set_yuv422(dev);
+       em28xx_set_outfmt(dev);
        em28xx_colorlevels_set_default(dev);
        em28xx_compression_disable(dev);
 
@@ -709,8 +719,8 @@ static int vidioc_g_fmt_vid_cap(struct f
 
        f->fmt.pix.width = dev->width;
        f->fmt.pix.height = dev->height;
-       f->fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
-       f->fmt.pix.bytesperline = dev->width * 2;
+       f->fmt.pix.pixelformat = dev->format->fourcc;
+       f->fmt.pix.bytesperline = (dev->width * dev->format->depth + 7) >> 3;
        f->fmt.pix.sizeimage = f->fmt.pix.bytesperline  * dev->height;
        f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
 
@@ -720,6 +730,17 @@ static int vidioc_g_fmt_vid_cap(struct f
 
        mutex_unlock(&dev->lock);
        return 0;
+}
+
+static struct em28xx_fmt *format_by_fourcc(unsigned int fourcc)
+{
+       unsigned int i;
+
+       for (i = 0; i < ARRAY_SIZE(format); i++)
+               if (format[i].fourcc == fourcc)
+                       return &format[i];
+
+       return NULL;
 }
 
 static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
@@ -732,6 +753,14 @@ static int vidioc_try_fmt_vid_cap(struct
        unsigned int          maxw   = norm_maxw(dev);
        unsigned int          maxh   = norm_maxh(dev);
        unsigned int          hscale, vscale;
+       struct em28xx_fmt     *fmt;
+
+       fmt = format_by_fourcc(f->fmt.pix.pixelformat);
+       if (!fmt) {
+               em28xx_videodbg("Fourcc format (%08x) invalid.\n",
+                               f->fmt.pix.pixelformat);
+               return -EINVAL;
+       }
 
        /* width must even because of the YUYV format
           height must be even because of interlacing */
@@ -770,9 +799,9 @@ static int vidioc_try_fmt_vid_cap(struct
 
        f->fmt.pix.width = width;
        f->fmt.pix.height = height;
-       f->fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
-       f->fmt.pix.bytesperline = width * 2;
-       f->fmt.pix.sizeimage = width * 2 * height;
+       f->fmt.pix.pixelformat = fmt->fourcc;
+       f->fmt.pix.bytesperline = (dev->width * fmt->depth + 7) >> 3;
+       f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * height;
        f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
        f->fmt.pix.field = V4L2_FIELD_INTERLACED;
 
@@ -785,6 +814,7 @@ static int vidioc_s_fmt_vid_cap(struct f
        struct em28xx_fh      *fh  = priv;
        struct em28xx         *dev = fh->dev;
        int                   rc;
+       struct em28xx_fmt     *fmt;
 
        rc = check_dev(dev);
        if (rc < 0)
@@ -793,6 +823,10 @@ static int vidioc_s_fmt_vid_cap(struct f
        mutex_lock(&dev->lock);
 
        vidioc_try_fmt_vid_cap(file, priv, f);
+
+       fmt = format_by_fourcc(f->fmt.pix.pixelformat);
+       if (!fmt)
+               return -EINVAL;
 
        if (videobuf_queue_is_busy(&fh->vb_vidq)) {
                em28xx_errdev("%s queue busy\n", __func__);
@@ -809,6 +843,7 @@ static int vidioc_s_fmt_vid_cap(struct f
        /* set new image size */
        dev->width = f->fmt.pix.width;
        dev->height = f->fmt.pix.height;
+       dev->format = fmt;
        get_scale(dev, dev->width, dev->height, &dev->hscale, &dev->vscale);
 
        em28xx_set_alternate(dev);
@@ -1346,15 +1381,13 @@ static int vidioc_querycap(struct file *
 }
 
 static int vidioc_enum_fmt_vid_cap(struct file *file, void  *priv,
-                                       struct v4l2_fmtdesc *fmtd)
-{
-       if (fmtd->index != 0)
-               return -EINVAL;
-
-       fmtd->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-       strcpy(fmtd->description, "Packed YUY2");
-       fmtd->pixelformat = V4L2_PIX_FMT_YUYV;
-       memset(fmtd->reserved, 0, sizeof(fmtd->reserved));
+                                       struct v4l2_fmtdesc *f)
+{
+       if (unlikely(f->index >= ARRAY_SIZE(format)))
+               return -EINVAL;
+
+       strlcpy(f->description, format[f->index].name, sizeof(f->description));
+       f->pixelformat = format[f->index].fourcc;
 
        return 0;
 }
@@ -2143,6 +2176,7 @@ static int em28xx_init_dev(struct em28xx
        dev->em28xx_write_regs_req = em28xx_write_regs_req;
        dev->em28xx_read_reg_req = em28xx_read_reg_req;
        dev->board.is_em2800 = em28xx_boards[dev->model].is_em2800;
+       dev->format = &format[0];
 
        em28xx_pre_card_setup(dev);
 
@@ -2564,3 +2598,4 @@ static void __exit em28xx_module_exit(vo
 
 module_init(em28xx_module_init);
 module_exit(em28xx_module_exit);
+
diff -r 66b4f7c10719 -r 005567806273 linux/drivers/media/video/em28xx/em28xx.h
--- a/linux/drivers/media/video/em28xx/em28xx.h Sat Dec 20 18:30:58 2008 +0100
+++ b/linux/drivers/media/video/em28xx/em28xx.h Sat Dec 20 18:32:30 2008 +0100
@@ -210,9 +210,12 @@ struct em28xx_usb_isoc_ctl {
 
 };
 
+/* Struct to enumberate video formats */
 struct em28xx_fmt {
        char  *name;
        u32   fourcc;          /* v4l2 format id */
+       int   depth;
+       int   reg;
 };
 
 /* buffer for one video frame */
@@ -438,6 +441,8 @@ struct em28xx {
        unsigned int stream_on:1;       /* Locks streams */
        unsigned int has_audio_class:1;
        unsigned int has_alsa_audio:1;
+
+       struct em28xx_fmt *format;
 
        struct em28xx_IR *ir;
 
@@ -577,7 +582,7 @@ int em28xx_audio_setup(struct em28xx *de
 
 int em28xx_colorlevels_set_default(struct em28xx *dev);
 int em28xx_capture_start(struct em28xx *dev, int start);
-int em28xx_outfmt_set_yuv422(struct em28xx *dev);
+int em28xx_set_outfmt(struct em28xx *dev);
 int em28xx_resolution_set(struct em28xx *dev);
 int em28xx_set_alternate(struct em28xx *dev);
 int em28xx_init_isoc(struct em28xx *dev, int max_packets,
diff -r 66b4f7c10719 -r 005567806273 linux/drivers/media/video/tuner-core.c
--- a/linux/drivers/media/video/tuner-core.c    Sat Dec 20 18:30:58 2008 +0100
+++ b/linux/drivers/media/video/tuner-core.c    Sat Dec 20 18:32:30 2008 +0100
@@ -737,6 +737,8 @@ static inline int set_mode(struct i2c_cl
        t->mode = mode;
 
        if (check_mode(t, cmd) == -EINVAL) {
+               tuner_dbg("Tuner doesn't support this mode. "
+                         "Putting tuner to sleep\n");
                t->mode = T_STANDBY;
                if (analog_ops->standby)
                        analog_ops->standby(&t->fe);
@@ -796,6 +798,8 @@ static int tuner_s_standby(struct v4l2_s
 {
        struct tuner *t = to_tuner(sd);
        struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops;
+
+       tuner_dbg("Putting tuner to sleep\n");
 
        if (check_mode(t, "TUNER_SET_STANDBY") == -EINVAL)
                return 0;
@@ -927,6 +931,11 @@ static int tuner_ioctl(struct v4l2_subde
                        return 0;
                }
        }
+       return -ENOIOCTLCMD;
+}
+#else
+static int tuner_ioctl(struct v4l2_subdev *sd, int cmd, void *arg)
+{
        return -ENOIOCTLCMD;
 }
 #endif


---

Patch is available at: 
http://linuxtv.org/hg/v4l-dvb/rev/005567806273e6373f262889afa1f4540befdc8c

_______________________________________________
linuxtv-commits mailing list
[email protected]
http://www.linuxtv.org/cgi-bin/mailman/listinfo/linuxtv-commits

Reply via email to