aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/radio/radio-mr800.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/radio/radio-mr800.c')
-rw-r--r--drivers/media/radio/radio-mr800.c85
1 files changed, 31 insertions, 54 deletions
diff --git a/drivers/media/radio/radio-mr800.c b/drivers/media/radio/radio-mr800.c
index ded25bfb366e..cab19d05e02f 100644
--- a/drivers/media/radio/radio-mr800.c
+++ b/drivers/media/radio/radio-mr800.c
@@ -43,6 +43,7 @@
43 * Douglas Schilling Landgraf <dougsland@gmail.com> and 43 * Douglas Schilling Landgraf <dougsland@gmail.com> and
44 * David Ellingsworth <david@identd.dyndns.org> 44 * David Ellingsworth <david@identd.dyndns.org>
45 * for discussion, help and support. 45 * for discussion, help and support.
46 * Version 0.11: Converted to v4l2_device.
46 * 47 *
47 * Many things to do: 48 * Many things to do:
48 * - Correct power managment of device (suspend & resume) 49 * - Correct power managment of device (suspend & resume)
@@ -59,7 +60,7 @@
59#include <linux/slab.h> 60#include <linux/slab.h>
60#include <linux/input.h> 61#include <linux/input.h>
61#include <linux/videodev2.h> 62#include <linux/videodev2.h>
62#include <media/v4l2-common.h> 63#include <media/v4l2-device.h>
63#include <media/v4l2-ioctl.h> 64#include <media/v4l2-ioctl.h>
64#include <linux/usb.h> 65#include <linux/usb.h>
65#include <linux/version.h> /* for KERNEL_VERSION MACRO */ 66#include <linux/version.h> /* for KERNEL_VERSION MACRO */
@@ -67,8 +68,8 @@
67/* driver and module definitions */ 68/* driver and module definitions */
68#define DRIVER_AUTHOR "Alexey Klimov <klimov.linux@gmail.com>" 69#define DRIVER_AUTHOR "Alexey Klimov <klimov.linux@gmail.com>"
69#define DRIVER_DESC "AverMedia MR 800 USB FM radio driver" 70#define DRIVER_DESC "AverMedia MR 800 USB FM radio driver"
70#define DRIVER_VERSION "0.10" 71#define DRIVER_VERSION "0.11"
71#define RADIO_VERSION KERNEL_VERSION(0, 1, 0) 72#define RADIO_VERSION KERNEL_VERSION(0, 1, 1)
72 73
73MODULE_AUTHOR(DRIVER_AUTHOR); 74MODULE_AUTHOR(DRIVER_AUTHOR);
74MODULE_DESCRIPTION(DRIVER_DESC); 75MODULE_DESCRIPTION(DRIVER_DESC);
@@ -113,38 +114,6 @@ static int radio_nr = -1;
113module_param(radio_nr, int, 0); 114module_param(radio_nr, int, 0);
114MODULE_PARM_DESC(radio_nr, "Radio Nr"); 115MODULE_PARM_DESC(radio_nr, "Radio Nr");
115 116
116static struct v4l2_queryctrl radio_qctrl[] = {
117 {
118 .id = V4L2_CID_AUDIO_MUTE,
119 .name = "Mute",
120 .minimum = 0,
121 .maximum = 1,
122 .step = 1,
123 .default_value = 1,
124 .type = V4L2_CTRL_TYPE_BOOLEAN,
125 },
126/* HINT: the disabled controls are only here to satify kradio and such apps */
127 { .id = V4L2_CID_AUDIO_VOLUME,
128 .flags = V4L2_CTRL_FLAG_DISABLED,
129 },
130 {
131 .id = V4L2_CID_AUDIO_BALANCE,
132 .flags = V4L2_CTRL_FLAG_DISABLED,
133 },
134 {
135 .id = V4L2_CID_AUDIO_BASS,
136 .flags = V4L2_CTRL_FLAG_DISABLED,
137 },
138 {
139 .id = V4L2_CID_AUDIO_TREBLE,
140 .flags = V4L2_CTRL_FLAG_DISABLED,
141 },
142 {
143 .id = V4L2_CID_AUDIO_LOUDNESS,
144 .flags = V4L2_CTRL_FLAG_DISABLED,
145 },
146};
147
148static int usb_amradio_probe(struct usb_interface *intf, 117static int usb_amradio_probe(struct usb_interface *intf,
149 const struct usb_device_id *id); 118 const struct usb_device_id *id);
150static void usb_amradio_disconnect(struct usb_interface *intf); 119static void usb_amradio_disconnect(struct usb_interface *intf);
@@ -159,6 +128,7 @@ struct amradio_device {
159 /* reference to USB and video device */ 128 /* reference to USB and video device */
160 struct usb_device *usbdev; 129 struct usb_device *usbdev;
161 struct video_device *videodev; 130 struct video_device *videodev;
131 struct v4l2_device v4l2_dev;
162 132
163 unsigned char *buffer; 133 unsigned char *buffer;
164 struct mutex lock; /* buffer locking */ 134 struct mutex lock; /* buffer locking */
@@ -329,6 +299,7 @@ static void usb_amradio_disconnect(struct usb_interface *intf)
329 299
330 usb_set_intfdata(intf, NULL); 300 usb_set_intfdata(intf, NULL);
331 video_unregister_device(radio->videodev); 301 video_unregister_device(radio->videodev);
302 v4l2_device_disconnect(&radio->v4l2_dev);
332} 303}
333 304
334/* vidioc_querycap - query device capabilities */ 305/* vidioc_querycap - query device capabilities */
@@ -463,14 +434,11 @@ static int vidioc_g_frequency(struct file *file, void *priv,
463static int vidioc_queryctrl(struct file *file, void *priv, 434static int vidioc_queryctrl(struct file *file, void *priv,
464 struct v4l2_queryctrl *qc) 435 struct v4l2_queryctrl *qc)
465{ 436{
466 int i; 437 switch (qc->id) {
467 438 case V4L2_CID_AUDIO_MUTE:
468 for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) { 439 return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);
469 if (qc->id && qc->id == radio_qctrl[i].id) {
470 memcpy(qc, &(radio_qctrl[i]), sizeof(*qc));
471 return 0;
472 }
473 } 440 }
441
474 return -EINVAL; 442 return -EINVAL;
475} 443}
476 444
@@ -671,34 +639,29 @@ static const struct v4l2_ioctl_ops usb_amradio_ioctl_ops = {
671 .vidioc_s_input = vidioc_s_input, 639 .vidioc_s_input = vidioc_s_input,
672}; 640};
673 641
674static void usb_amradio_device_release(struct video_device *videodev) 642static void usb_amradio_video_device_release(struct video_device *videodev)
675{ 643{
676 struct amradio_device *radio = video_get_drvdata(videodev); 644 struct amradio_device *radio = video_get_drvdata(videodev);
677 645
678 /* we call v4l to free radio->videodev */ 646 /* we call v4l to free radio->videodev */
679 video_device_release(videodev); 647 video_device_release(videodev);
680 648
649 v4l2_device_unregister(&radio->v4l2_dev);
650
681 /* free rest memory */ 651 /* free rest memory */
682 kfree(radio->buffer); 652 kfree(radio->buffer);
683 kfree(radio); 653 kfree(radio);
684} 654}
685 655
686/* V4L2 interface */
687static struct video_device amradio_videodev_template = {
688 .name = "AverMedia MR 800 USB FM Radio",
689 .fops = &usb_amradio_fops,
690 .ioctl_ops = &usb_amradio_ioctl_ops,
691 .release = usb_amradio_device_release,
692};
693
694/* check if the device is present and register with v4l and usb if it is */ 656/* check if the device is present and register with v4l and usb if it is */
695static int usb_amradio_probe(struct usb_interface *intf, 657static int usb_amradio_probe(struct usb_interface *intf,
696 const struct usb_device_id *id) 658 const struct usb_device_id *id)
697{ 659{
698 struct amradio_device *radio; 660 struct amradio_device *radio;
661 struct v4l2_device *v4l2_dev;
699 int retval; 662 int retval;
700 663
701 radio = kmalloc(sizeof(struct amradio_device), GFP_KERNEL); 664 radio = kzalloc(sizeof(struct amradio_device), GFP_KERNEL);
702 665
703 if (!radio) { 666 if (!radio) {
704 dev_err(&intf->dev, "kmalloc for amradio_device failed\n"); 667 dev_err(&intf->dev, "kmalloc for amradio_device failed\n");
@@ -713,6 +676,15 @@ static int usb_amradio_probe(struct usb_interface *intf,
713 return -ENOMEM; 676 return -ENOMEM;
714 } 677 }
715 678
679 v4l2_dev = &radio->v4l2_dev;
680 retval = v4l2_device_register(&intf->dev, v4l2_dev);
681 if (retval < 0) {
682 dev_err(&intf->dev, "couldn't register v4l2_device\n");
683 kfree(radio->buffer);
684 kfree(radio);
685 return retval;
686 }
687
716 radio->videodev = video_device_alloc(); 688 radio->videodev = video_device_alloc();
717 689
718 if (!radio->videodev) { 690 if (!radio->videodev) {
@@ -722,8 +694,11 @@ static int usb_amradio_probe(struct usb_interface *intf,
722 return -ENOMEM; 694 return -ENOMEM;
723 } 695 }
724 696
725 memcpy(radio->videodev, &amradio_videodev_template, 697 strlcpy(radio->videodev->name, v4l2_dev->name, sizeof(radio->videodev->name));
726 sizeof(amradio_videodev_template)); 698 radio->videodev->v4l2_dev = v4l2_dev;
699 radio->videodev->fops = &usb_amradio_fops;
700 radio->videodev->ioctl_ops = &usb_amradio_ioctl_ops;
701 radio->videodev->release = usb_amradio_video_device_release;
727 702
728 radio->removed = 0; 703 radio->removed = 0;
729 radio->users = 0; 704 radio->users = 0;
@@ -734,10 +709,12 @@ static int usb_amradio_probe(struct usb_interface *intf,
734 mutex_init(&radio->lock); 709 mutex_init(&radio->lock);
735 710
736 video_set_drvdata(radio->videodev, radio); 711 video_set_drvdata(radio->videodev, radio);
712
737 retval = video_register_device(radio->videodev, VFL_TYPE_RADIO, radio_nr); 713 retval = video_register_device(radio->videodev, VFL_TYPE_RADIO, radio_nr);
738 if (retval < 0) { 714 if (retval < 0) {
739 dev_err(&intf->dev, "could not register video device\n"); 715 dev_err(&intf->dev, "could not register video device\n");
740 video_device_release(radio->videodev); 716 video_device_release(radio->videodev);
717 v4l2_device_unregister(v4l2_dev);
741 kfree(radio->buffer); 718 kfree(radio->buffer);
742 kfree(radio); 719 kfree(radio);
743 return -EIO; 720 return -EIO;