[media] au0828: frequency handling fixes
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / media / usb / au0828 / au0828-video.c
index 11316f2f2e421dc4b3c91f5ddfc987a6319ea9f3..8562cca80b362e95734e5a05b6ff235211fad142 100644 (file)
@@ -1241,20 +1241,25 @@ static int vidioc_queryctrl(struct file *file, void *priv,
 static int vidioc_querycap(struct file *file, void  *priv,
                           struct v4l2_capability *cap)
 {
-       struct au0828_fh *fh  = priv;
+       struct video_device *vdev = video_devdata(file);
+       struct au0828_fh *fh = priv;
        struct au0828_dev *dev = fh->dev;
 
        strlcpy(cap->driver, "au0828", sizeof(cap->driver));
        strlcpy(cap->card, dev->board.name, sizeof(cap->card));
-       strlcpy(cap->bus_info, dev->v4l2_dev.name, sizeof(cap->bus_info));
+       usb_make_path(dev->usbdev, cap->bus_info, sizeof(cap->bus_info));
 
-       /*set the device capabilities */
-       cap->capabilities = V4L2_CAP_VIDEO_CAPTURE |
-               V4L2_CAP_VBI_CAPTURE |
-               V4L2_CAP_AUDIO |
+       /* set the device capabilities */
+       cap->device_caps = V4L2_CAP_AUDIO |
                V4L2_CAP_READWRITE |
                V4L2_CAP_STREAMING |
                V4L2_CAP_TUNER;
+       if (vdev->vfl_type == VFL_TYPE_GRABBER)
+               cap->device_caps |= V4L2_CAP_VIDEO_CAPTURE;
+       else
+               cap->device_caps |= V4L2_CAP_VBI_CAPTURE;
+       cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS |
+               V4L2_CAP_VBI_CAPTURE | V4L2_CAP_VIDEO_CAPTURE;
        return 0;
 }
 
@@ -1320,7 +1325,7 @@ out:
        return rc;
 }
 
-static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id norm)
+static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id norm)
 {
        struct au0828_fh *fh = priv;
        struct au0828_dev *dev = fh->dev;
@@ -1332,7 +1337,7 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id * norm)
           have to make the au0828 bridge adjust the size of its capture
           buffer, which is currently hardcoded at 720x480 */
 
-       v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_std, *norm);
+       v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_std, norm);
        dev->std_set_in_tuner_core = 1;
 
        if (dev->dvb.frontend && dev->dvb.frontend->ops.analog_ops.i2c_gate_ctrl)
@@ -1537,7 +1542,8 @@ static int vidioc_g_frequency(struct file *file, void *priv,
        struct au0828_fh *fh = priv;
        struct au0828_dev *dev = fh->dev;
 
-       freq->type = V4L2_TUNER_ANALOG_TV;
+       if (freq->tuner != 0)
+               return -EINVAL;
        freq->frequency = dev->ctrl_freq;
        return 0;
 }
@@ -1547,13 +1553,10 @@ static int vidioc_s_frequency(struct file *file, void *priv,
 {
        struct au0828_fh *fh = priv;
        struct au0828_dev *dev = fh->dev;
+       struct v4l2_frequency new_freq = *freq;
 
        if (freq->tuner != 0)
                return -EINVAL;
-       if (freq->type != V4L2_TUNER_ANALOG_TV)
-               return -EINVAL;
-
-       dev->ctrl_freq = freq->frequency;
 
        if (dev->dvb.frontend && dev->dvb.frontend->ops.analog_ops.i2c_gate_ctrl)
                dev->dvb.frontend->ops.analog_ops.i2c_gate_ctrl(dev->dvb.frontend, 1);
@@ -1568,6 +1571,9 @@ static int vidioc_s_frequency(struct file *file, void *priv,
        }
 
        v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_frequency, freq);
+       /* Get the actual set (and possibly clamped) frequency */
+       v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, g_frequency, &new_freq);
+       dev->ctrl_freq = new_freq.frequency;
 
        if (dev->dvb.frontend && dev->dvb.frontend->ops.analog_ops.i2c_gate_ctrl)
                dev->dvb.frontend->ops.analog_ops.i2c_gate_ctrl(dev->dvb.frontend, 0);
@@ -1754,7 +1760,7 @@ static int vidioc_g_register(struct file *file, void *priv,
 }
 
 static int vidioc_s_register(struct file *file, void *priv,
-                            struct v4l2_dbg_register *reg)
+                            const struct v4l2_dbg_register *reg)
 {
        struct au0828_fh *fh = priv;
        struct au0828_dev *dev = fh->dev;
@@ -1971,6 +1977,7 @@ int au0828_analog_register(struct au0828_dev *dev,
        dev->frame_size = dev->field_size << 1;
        dev->bytesperline = dev->width << 1;
        dev->ctrl_ainput = 0;
+       dev->ctrl_freq = 960;
 
        /* allocate and fill v4l2 video struct */
        dev->vdev = video_device_alloc();