-/* A driver for the D-Link DSB-R100 USB radio. The R100 plugs
- into both the USB and an analog audio input, so this thing
+/* A driver for the D-Link DSB-R100 USB radio and Gemtek USB Radio 21.
+ The device plugs into both the USB and an analog audio input, so this thing
only deals with initialisation and frequency setting, the
audio data has to be handled by a sound driver.
History:
+ Version 0.44:
+ Add suspend/resume functions, fix unplug of device,
+ a lot of cleanups and fixes by Alexey Klimov <klimov.linux@gmail.com>
+
Version 0.43:
Oliver Neukum: avoided DMA coherency issue
*/
#include <linux/version.h> /* for KERNEL_VERSION MACRO */
-#define DRIVER_VERSION "v0.43"
-#define RADIO_VERSION KERNEL_VERSION(0, 4, 3)
+#define DRIVER_VERSION "v0.44"
+#define RADIO_VERSION KERNEL_VERSION(0, 4, 4)
static struct v4l2_queryctrl radio_qctrl[] = {
{
static int usb_dsbr100_probe(struct usb_interface *intf,
const struct usb_device_id *id);
static void usb_dsbr100_disconnect(struct usb_interface *intf);
-static int usb_dsbr100_open(struct inode *inode, struct file *file);
-static int usb_dsbr100_close(struct inode *inode, struct file *file);
+static int usb_dsbr100_open(struct file *file);
+static int usb_dsbr100_close(struct file *file);
static int usb_dsbr100_suspend(struct usb_interface *intf,
pm_message_t message);
static int usb_dsbr100_resume(struct usb_interface *intf);
int muted;
};
-
static struct usb_device_id usb_dsbr100_device_table [] = {
{ USB_DEVICE(DSB100_VENDOR, DSB100_PRODUCT) },
{ } /* Terminating entry */
dev_err(&radio->usbdev->dev,
"%s - usb_control_msg returned %i, request %i\n",
__func__, retval, request);
- return -1;
+ return retval;
}
-
/* switch off radio */
static int dsbr100_stop(struct dsbr100_device *radio)
{
dev_err(&radio->usbdev->dev,
"%s - usb_control_msg returned %i, request %i\n",
__func__, retval, request);
- return -1;
+ return retval;
}
dev_err(&radio->usbdev->dev,
"%s - usb_control_msg returned %i, request %i\n",
__func__, retval, request);
- return -1;
+ return retval;
}
/* return the device status. This is, in effect, just whether it
mutex_unlock(&radio->lock);
}
-
/* USB subsystem interface begins here */
-/* handle unplugging of the device, release data structures
-if nothing keeps us from doing it. If something is still
-keeping us busy, the release callback of v4l will take care
-of releasing it. */
+/*
+ * Handle unplugging of the device.
+ * We call video_unregister_device in any case.
+ * The last function called in this procedure is
+ * usb_dsbr100_video_device_release
+ */
static void usb_dsbr100_disconnect(struct usb_interface *intf)
{
struct dsbr100_device *radio = usb_get_intfdata(intf);
radio->curfreq = f->frequency;
retval = dsbr100_setfreq(radio, radio->curfreq);
- if (retval == -1)
+ if (retval < 0)
dev_warn(&radio->usbdev->dev, "Set frequency failed\n");
return 0;
}
case V4L2_CID_AUDIO_MUTE:
if (ctrl->value) {
retval = dsbr100_stop(radio);
- if (retval == -1) {
+ if (retval < 0) {
dev_warn(&radio->usbdev->dev,
"Radio did not respond properly\n");
return -EBUSY;
}
} else {
retval = dsbr100_start(radio);
- if (retval == -1) {
+ if (retval < 0) {
dev_warn(&radio->usbdev->dev,
"Radio did not respond properly\n");
return -EBUSY;
return 0;
}
-static int usb_dsbr100_open(struct inode *inode, struct file *file)
+static int usb_dsbr100_open(struct file *file)
{
struct dsbr100_device *radio = video_drvdata(file);
int retval;
}
retval = dsbr100_setfreq(radio, radio->curfreq);
- if (retval == -1)
+ if (retval < 0)
dev_warn(&radio->usbdev->dev,
"set frequency failed\n");
return 0;
}
-static int usb_dsbr100_close(struct inode *inode, struct file *file)
+static int usb_dsbr100_close(struct file *file)
{
struct dsbr100_device *radio = video_drvdata(file);
int retval;
radio->users = 0;
if (!radio->removed) {
retval = dsbr100_stop(radio);
- if (retval == -1) {
+ if (retval < 0) {
dev_warn(&radio->usbdev->dev,
"dsbr100_stop failed\n");
}
int retval;
retval = dsbr100_stop(radio);
- if (retval == -1)
+ if (retval < 0)
dev_warn(&intf->dev, "dsbr100_stop failed\n");
dev_info(&intf->dev, "going into suspend..\n");
int retval;
retval = dsbr100_start(radio);
- if (retval == -1)
+ if (retval < 0)
dev_warn(&intf->dev, "dsbr100_start failed\n");
dev_info(&intf->dev, "coming out of suspend..\n");
return 0;
}
+/* free data structures */
static void usb_dsbr100_video_device_release(struct video_device *videodev)
{
struct dsbr100_device *radio = videodev_to_radio(videodev);
}
/* File system interface */
-static const struct file_operations usb_dsbr100_fops = {
+static const struct v4l2_file_operations usb_dsbr100_fops = {
.owner = THIS_MODULE,
.open = usb_dsbr100_open,
.release = usb_dsbr100_close,
.ioctl = video_ioctl2,
-#ifdef CONFIG_COMPAT
- .compat_ioctl = v4l_compat_ioctl32,
-#endif
- .llseek = no_llseek,
};
static const struct v4l2_ioctl_ops usb_dsbr100_ioctl_ops = {
.release = usb_dsbr100_video_device_release,
};
-/* check if the device is present and register with v4l and
-usb if it is */
+/* check if the device is present and register with v4l and usb if it is */
static int usb_dsbr100_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{