[media] usbvision: frequency fixes
authorHans Verkuil <hans.verkuil@cisco.com>
Mon, 20 Jul 2015 12:59:33 +0000 (09:59 -0300)
committerMauro Carvalho Chehab <mchehab@osg.samsung.com>
Tue, 11 Aug 2015 09:52:31 +0000 (06:52 -0300)
- setup initial radio and tv frequencies.
- set/get the correct frequency (radio vs tv).
- disable tuner/freq ioctls if there is no tuner.
- fix some tuner index checks.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
drivers/media/usb/usbvision/usbvision-video.c
drivers/media/usb/usbvision/usbvision.h

index f526712a64351acbcac783c8dfa3b99d56b5c83c..dc0e034fc6764ba2793c528cfc3df26f2deb4d97 100644 (file)
@@ -608,14 +608,13 @@ static int vidioc_g_tuner(struct file *file, void *priv,
 {
        struct usb_usbvision *usbvision = video_drvdata(file);
 
-       if (!usbvision->have_tuner || vt->index)        /* Only tuner 0 */
+       if (vt->index)  /* Only tuner 0 */
                return -EINVAL;
-       if (usbvision->radio) {
+       if (vt->type == V4L2_TUNER_RADIO)
                strcpy(vt->name, "Radio");
-               vt->type = V4L2_TUNER_RADIO;
-       } else {
+       else
                strcpy(vt->name, "Television");
-       }
+
        /* Let clients fill in the remainder of this struct */
        call_all(usbvision, tuner, g_tuner, vt);
 
@@ -627,8 +626,8 @@ static int vidioc_s_tuner(struct file *file, void *priv,
 {
        struct usb_usbvision *usbvision = video_drvdata(file);
 
-       /* Only no or one tuner for now */
-       if (!usbvision->have_tuner || vt->index)
+       /* Only one tuner for now */
+       if (vt->index)
                return -EINVAL;
        /* let clients handle this */
        call_all(usbvision, tuner, s_tuner, vt);
@@ -641,12 +640,13 @@ static int vidioc_g_frequency(struct file *file, void *priv,
 {
        struct usb_usbvision *usbvision = video_drvdata(file);
 
-       freq->tuner = 0; /* Only one tuner */
-       if (usbvision->radio)
-               freq->type = V4L2_TUNER_RADIO;
+       /* Only one tuner */
+       if (freq->tuner)
+               return -EINVAL;
+       if (freq->type == V4L2_TUNER_RADIO)
+               freq->frequency = usbvision->radio_freq;
        else
-               freq->type = V4L2_TUNER_ANALOG_TV;
-       freq->frequency = usbvision->freq;
+               freq->frequency = usbvision->tv_freq;
 
        return 0;
 }
@@ -655,13 +655,18 @@ static int vidioc_s_frequency(struct file *file, void *priv,
                                const struct v4l2_frequency *freq)
 {
        struct usb_usbvision *usbvision = video_drvdata(file);
+       struct v4l2_frequency new_freq = *freq;
 
-       /* Only no or one tuner for now */
-       if (!usbvision->have_tuner || freq->tuner)
+       /* Only one tuner for now */
+       if (freq->tuner)
                return -EINVAL;
 
-       usbvision->freq = freq->frequency;
        call_all(usbvision, tuner, s_frequency, freq);
+       call_all(usbvision, tuner, g_frequency, &new_freq);
+       if (freq->type == V4L2_TUNER_RADIO)
+               usbvision->radio_freq = new_freq.frequency;
+       else
+               usbvision->tv_freq = new_freq.frequency;
 
        return 0;
 }
@@ -1287,6 +1292,12 @@ static int usbvision_register_video(struct usb_usbvision *usbvision)
        /* Video Device: */
        usbvision_vdev_init(usbvision, &usbvision->vdev,
                              &usbvision_video_template, "USBVision Video");
+       if (!usbvision->have_tuner) {
+               v4l2_disable_ioctl(&usbvision->vdev, VIDIOC_G_FREQUENCY);
+               v4l2_disable_ioctl(&usbvision->vdev, VIDIOC_S_TUNER);
+               v4l2_disable_ioctl(&usbvision->vdev, VIDIOC_G_FREQUENCY);
+               v4l2_disable_ioctl(&usbvision->vdev, VIDIOC_S_TUNER);
+       }
        if (video_register_device(&usbvision->vdev, VFL_TYPE_GRABBER, video_nr) < 0)
                goto err_exit;
        printk(KERN_INFO "USBVision[%d]: registered USBVision Video device %s [v4l2]\n",
@@ -1403,9 +1414,10 @@ static void usbvision_configure_video(struct usb_usbvision *usbvision)
        }
 
        usbvision->tvnorm_id = usbvision_device_data[model].video_norm;
-
        usbvision->video_inputs = usbvision_device_data[model].video_channels;
        usbvision->ctl_input = 0;
+       usbvision->radio_freq = 87.5 * 16000;
+       usbvision->tv_freq = 400 * 16;
 
        /* This should be here to make i2c clients to be able to register */
        /* first switch off audio */
index 4dbb4218b771cedf553b21fce891d0298c440824..4f2e4fde38f24fe2b7b4aec1ba00460b3e658d3a 100644 (file)
@@ -378,7 +378,8 @@ struct usb_usbvision {
        int bridge_type;                                                /* NT1003, NT1004, NT1005 */
        int radio;
        int video_inputs;                                               /* # of inputs */
-       unsigned long freq;
+       unsigned long radio_freq;
+       unsigned long tv_freq;
        int audio_mute;
        int audio_channel;
        int isoc_mode;                                                  /* format of video data for the usb isoc-transfer */