]> err.no Git - linux-2.6/blobdiff - drivers/media/video/saa7134/saa7134-empress.c
V4L/DVB (8428): videodev: rename 'dev' to 'parent'
[linux-2.6] / drivers / media / video / saa7134 / saa7134-empress.c
index 94b2585bdf5b095f6d5edc9be8852e4741cbe77f..3854cc29752d30472be07839bf08d4cc7c9e02f5 100644 (file)
@@ -110,9 +110,10 @@ static int ts_release(struct inode *inode, struct file *file)
 {
        struct saa7134_dev *dev = file->private_data;
 
+       mutex_lock(&dev->empress_tsq.vb_lock);
+
        videobuf_stop(&dev->empress_tsq);
        videobuf_mmap_free(&dev->empress_tsq);
-       dev->empress_users--;
 
        /* stop the encoder */
        ts_reset_encoder(dev);
@@ -121,6 +122,10 @@ static int ts_release(struct inode *inode, struct file *file)
        saa_writeb(SAA7134_AUDIO_MUTE_CTRL,
                saa_readb(SAA7134_AUDIO_MUTE_CTRL) | (1 << 6));
 
+       dev->empress_users--;
+
+       mutex_unlock(&dev->empress_tsq.vb_lock);
+
        return 0;
 }
 
@@ -203,7 +208,7 @@ static int empress_s_input(struct file *file, void *priv, unsigned int i)
        return 0;
 }
 
-static int empress_enum_fmt_cap(struct file *file, void  *priv,
+static int empress_enum_fmt_vid_cap(struct file *file, void  *priv,
                                        struct v4l2_fmtdesc *f)
 {
        if (f->index != 0)
@@ -215,7 +220,7 @@ static int empress_enum_fmt_cap(struct file *file, void  *priv,
        return 0;
 }
 
-static int empress_g_fmt_cap(struct file *file, void *priv,
+static int empress_g_fmt_vid_cap(struct file *file, void *priv,
                                struct v4l2_format *f)
 {
        struct saa7134_dev *dev = file->private_data;
@@ -228,7 +233,7 @@ static int empress_g_fmt_cap(struct file *file, void *priv,
        return 0;
 }
 
-static int empress_s_fmt_cap(struct file *file, void *priv,
+static int empress_s_fmt_vid_cap(struct file *file, void *priv,
                                struct v4l2_format *f)
 {
        struct saa7134_dev *dev = file->private_data;
@@ -289,10 +294,20 @@ static int empress_streamoff(struct file *file, void *priv,
        return videobuf_streamoff(&dev->empress_tsq);
 }
 
+static int saa7134_i2c_call_saa6752(struct saa7134_dev *dev,
+                                             unsigned int cmd, void *arg)
+{
+       if (dev->mpeg_i2c_client == NULL)
+               return -EINVAL;
+       return dev->mpeg_i2c_client->driver->command(dev->mpeg_i2c_client,
+                                                               cmd, arg);
+}
+
 static int empress_s_ext_ctrls(struct file *file, void *priv,
                               struct v4l2_ext_controls *ctrls)
 {
        struct saa7134_dev *dev = file->private_data;
+       int err;
 
        /* count == 0 is abused in saa6752hs.c, so that special
                case is handled here explicitly. */
@@ -302,10 +317,10 @@ static int empress_s_ext_ctrls(struct file *file, void *priv,
        if (ctrls->ctrl_class != V4L2_CTRL_CLASS_MPEG)
                return -EINVAL;
 
-       saa7134_i2c_call_clients(dev, VIDIOC_S_EXT_CTRLS, ctrls);
+       err = saa7134_i2c_call_saa6752(dev, VIDIOC_S_EXT_CTRLS, ctrls);
        ts_init_encoder(dev);
 
-       return 0;
+       return err;
 }
 
 static int empress_g_ext_ctrls(struct file *file, void *priv,
@@ -315,9 +330,62 @@ static int empress_g_ext_ctrls(struct file *file, void *priv,
 
        if (ctrls->ctrl_class != V4L2_CTRL_CLASS_MPEG)
                return -EINVAL;
-       saa7134_i2c_call_clients(dev, VIDIOC_G_EXT_CTRLS, ctrls);
+       return saa7134_i2c_call_saa6752(dev, VIDIOC_G_EXT_CTRLS, ctrls);
+}
 
-       return 0;
+static int empress_queryctrl(struct file *file, void *priv,
+                                       struct v4l2_queryctrl *c)
+{
+       static const u32 user_ctrls[] = {
+               V4L2_CID_USER_CLASS,
+               V4L2_CID_BRIGHTNESS,
+               V4L2_CID_CONTRAST,
+               V4L2_CID_SATURATION,
+               V4L2_CID_HUE,
+               V4L2_CID_AUDIO_VOLUME,
+               V4L2_CID_AUDIO_MUTE,
+               V4L2_CID_HFLIP,
+               0
+       };
+
+       static const u32 mpeg_ctrls[] = {
+               V4L2_CID_MPEG_CLASS,
+               V4L2_CID_MPEG_STREAM_TYPE,
+               V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ,
+               V4L2_CID_MPEG_AUDIO_ENCODING,
+               V4L2_CID_MPEG_AUDIO_L2_BITRATE,
+               V4L2_CID_MPEG_VIDEO_ENCODING,
+               V4L2_CID_MPEG_VIDEO_ASPECT,
+               V4L2_CID_MPEG_VIDEO_BITRATE_MODE,
+               V4L2_CID_MPEG_VIDEO_BITRATE,
+               V4L2_CID_MPEG_VIDEO_BITRATE_PEAK,
+               0
+       };
+       static const u32 *ctrl_classes[] = {
+               user_ctrls,
+               mpeg_ctrls,
+               NULL
+       };
+       struct saa7134_dev *dev = file->private_data;
+
+       c->id = v4l2_ctrl_next(ctrl_classes, c->id);
+       if (c->id == 0)
+               return -EINVAL;
+       if (c->id == V4L2_CID_USER_CLASS || c->id == V4L2_CID_MPEG_CLASS)
+               return v4l2_ctrl_query_fill_std(c);
+       if (V4L2_CTRL_ID2CLASS(c->id) != V4L2_CTRL_CLASS_MPEG)
+               return saa7134_queryctrl(file, priv, c);
+       return saa7134_i2c_call_saa6752(dev, VIDIOC_QUERYCTRL, c);
+}
+
+static int empress_querymenu(struct file *file, void *priv,
+                                       struct v4l2_querymenu *c)
+{
+       struct saa7134_dev *dev = file->private_data;
+
+       if (V4L2_CTRL_ID2CLASS(c->id) != V4L2_CTRL_CLASS_MPEG)
+               return -EINVAL;
+       return saa7134_i2c_call_saa6752(dev, VIDIOC_QUERYMENU, c);
 }
 
 static const struct file_operations ts_fops =
@@ -343,9 +411,9 @@ static struct video_device saa7134_empress_template =
        .minor         = -1,
 
        .vidioc_querycap                = empress_querycap,
-       .vidioc_enum_fmt_cap            = empress_enum_fmt_cap,
-       .vidioc_s_fmt_cap               = empress_s_fmt_cap,
-       .vidioc_g_fmt_cap               = empress_g_fmt_cap,
+       .vidioc_enum_fmt_vid_cap        = empress_enum_fmt_vid_cap,
+       .vidioc_s_fmt_vid_cap           = empress_s_fmt_vid_cap,
+       .vidioc_g_fmt_vid_cap           = empress_g_fmt_vid_cap,
        .vidioc_reqbufs                 = empress_reqbufs,
        .vidioc_querybuf                = empress_querybuf,
        .vidioc_qbuf                    = empress_qbuf,
@@ -358,7 +426,8 @@ static struct video_device saa7134_empress_template =
        .vidioc_g_input                 = empress_g_input,
        .vidioc_s_input                 = empress_s_input,
 
-       .vidioc_queryctrl               = saa7134_queryctrl,
+       .vidioc_queryctrl               = empress_queryctrl,
+       .vidioc_querymenu               = empress_querymenu,
        .vidioc_g_ctrl                  = saa7134_g_ctrl,
        .vidioc_s_ctrl                  = saa7134_s_ctrl,
 
@@ -396,7 +465,7 @@ static int empress_init(struct saa7134_dev *dev)
        if (NULL == dev->empress_dev)
                return -ENOMEM;
        *(dev->empress_dev) = saa7134_empress_template;
-       dev->empress_dev->dev     = &dev->pci->dev;
+       dev->empress_dev->parent  = &dev->pci->dev;
        dev->empress_dev->release = video_device_release;
        snprintf(dev->empress_dev->name, sizeof(dev->empress_dev->name),
                 "%s empress (%s)", dev->name,