aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/radio
diff options
context:
space:
mode:
authorTobias Lorenz <tobias.lorenz@gmx.net>2009-06-20 18:00:06 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-09-12 11:17:11 -0400
commit721f59ed612477a9f83f3f3a222a14d16505c1a4 (patch)
tree3fba0f8d336103debf9e49097bb99b706a6adaf9 /drivers/media/radio
parent86d710146fb9975f04c505ec78caa43d227c1018 (diff)
V4L/DVB (12142): radio-si470x: Add suport for RDS endpoint interrupt mode
Add support for interrupt mode for RDS endpoint, instead of polling. Improves RDS reception significantly Signed-off-by: Edouard Lafargue <edouard@lafargue.name> Acked-by: Tobias Lorenz <tobias.lorenz@gmx.net> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/radio')
-rw-r--r--drivers/media/radio/radio-si470x.c350
1 files changed, 192 insertions, 158 deletions
diff --git a/drivers/media/radio/radio-si470x.c b/drivers/media/radio/radio-si470x.c
index e85f318b4d2b..41f304325074 100644
--- a/drivers/media/radio/radio-si470x.c
+++ b/drivers/media/radio/radio-si470x.c
@@ -106,20 +106,24 @@
106 * Tobias Lorenz <tobias.lorenz@gmx.net> 106 * Tobias Lorenz <tobias.lorenz@gmx.net>
107 * - add LED status output 107 * - add LED status output
108 * - get HW/SW version from scratchpad 108 * - get HW/SW version from scratchpad
109 * 2009-06-16 Edouard Lafargue <edouard@lafargue.name>
110 * Version 1.0.10
111 * - add support for interrupt mode for RDS endpoint,
112 * instead of polling.
113 * Improves RDS reception significantly
109 * 114 *
110 * ToDo: 115 * ToDo:
111 * - add firmware download/update support 116 * - add firmware download/update support
112 * - RDS support: interrupt mode, instead of polling
113 */ 117 */
114 118
115 119
116/* driver definitions */ 120/* driver definitions */
117#define DRIVER_AUTHOR "Tobias Lorenz <tobias.lorenz@gmx.net>" 121#define DRIVER_AUTHOR "Tobias Lorenz <tobias.lorenz@gmx.net>"
118#define DRIVER_NAME "radio-si470x" 122#define DRIVER_NAME "radio-si470x"
119#define DRIVER_KERNEL_VERSION KERNEL_VERSION(1, 0, 9) 123#define DRIVER_KERNEL_VERSION KERNEL_VERSION(1, 0, 10)
120#define DRIVER_CARD "Silicon Labs Si470x FM Radio Receiver" 124#define DRIVER_CARD "Silicon Labs Si470x FM Radio Receiver"
121#define DRIVER_DESC "USB radio driver for Si470x FM Radio Receivers" 125#define DRIVER_DESC "USB radio driver for Si470x FM Radio Receivers"
122#define DRIVER_VERSION "1.0.9" 126#define DRIVER_VERSION "1.0.10"
123 127
124 128
125/* kernel includes */ 129/* kernel includes */
@@ -218,16 +222,6 @@ static unsigned short max_rds_errors = 1;
218module_param(max_rds_errors, ushort, 0644); 222module_param(max_rds_errors, ushort, 0644);
219MODULE_PARM_DESC(max_rds_errors, "RDS maximum block errors: *1*"); 223MODULE_PARM_DESC(max_rds_errors, "RDS maximum block errors: *1*");
220 224
221/* RDS poll frequency */
222static unsigned int rds_poll_time = 40;
223/* 40 is used by the original USBRadio.exe */
224/* 50 is used by radio-cadet */
225/* 75 should be okay */
226/* 80 is the usual RDS receive interval */
227module_param(rds_poll_time, uint, 0644);
228MODULE_PARM_DESC(rds_poll_time, "RDS poll time (ms): *40*");
229
230
231 225
232/************************************************************************** 226/**************************************************************************
233 * Register Definitions 227 * Register Definitions
@@ -450,6 +444,12 @@ struct si470x_device {
450 struct usb_interface *intf; 444 struct usb_interface *intf;
451 struct video_device *videodev; 445 struct video_device *videodev;
452 446
447 /* Interrupt endpoint handling */
448 char *int_in_buffer;
449 struct usb_endpoint_descriptor *int_in_endpoint;
450 struct urb *int_in_urb;
451 int int_in_running;
452
453 /* driver management */ 453 /* driver management */
454 unsigned int users; 454 unsigned int users;
455 unsigned char disconnected; 455 unsigned char disconnected;
@@ -459,7 +459,6 @@ struct si470x_device {
459 unsigned short registers[RADIO_REGISTER_NUM]; 459 unsigned short registers[RADIO_REGISTER_NUM];
460 460
461 /* RDS receive buffer */ 461 /* RDS receive buffer */
462 struct delayed_work work;
463 wait_queue_head_t read_queue; 462 wait_queue_head_t read_queue;
464 struct mutex lock; /* buffer locking */ 463 struct mutex lock; /* buffer locking */
465 unsigned char *buffer; /* size is always multiple of three */ 464 unsigned char *buffer; /* size is always multiple of three */
@@ -865,43 +864,6 @@ static int si470x_get_all_registers(struct si470x_device *radio)
865 864
866 865
867/************************************************************************** 866/**************************************************************************
868 * General Driver Functions - RDS_REPORT
869 **************************************************************************/
870
871/*
872 * si470x_get_rds_registers - read rds registers
873 */
874static int si470x_get_rds_registers(struct si470x_device *radio)
875{
876 unsigned char buf[RDS_REPORT_SIZE];
877 int retval;
878 int size;
879 unsigned char regnr;
880
881 buf[0] = RDS_REPORT;
882
883 retval = usb_interrupt_msg(radio->usbdev,
884 usb_rcvintpipe(radio->usbdev, 1),
885 (void *) &buf, sizeof(buf), &size, usb_timeout);
886 if (size != sizeof(buf))
887 printk(KERN_WARNING DRIVER_NAME ": si470x_get_rds_registers: "
888 "return size differs: %d != %zu\n", size, sizeof(buf));
889 if (retval < 0)
890 printk(KERN_WARNING DRIVER_NAME ": si470x_get_rds_registers: "
891 "usb_interrupt_msg returned %d\n", retval);
892
893 if (retval >= 0)
894 for (regnr = 0; regnr < RDS_REGISTER_NUM; regnr++)
895 radio->registers[STATUSRSSI + regnr] =
896 get_unaligned_be16(
897 &buf[regnr * RADIO_REGISTER_SIZE + 1]);
898
899 return (retval < 0) ? -EINVAL : 0;
900}
901
902
903
904/**************************************************************************
905 * General Driver Functions - LED_REPORT 867 * General Driver Functions - LED_REPORT
906 **************************************************************************/ 868 **************************************************************************/
907 869
@@ -959,102 +921,118 @@ static int si470x_get_scratch_page_versions(struct si470x_device *radio)
959 **************************************************************************/ 921 **************************************************************************/
960 922
961/* 923/*
962 * si470x_rds - rds processing function 924 * si470x_int_in_callback - rds callback and processing function
925 *
926 * TODO: do we need to use mutex locks in some sections?
963 */ 927 */
964static void si470x_rds(struct si470x_device *radio) 928static void si470x_int_in_callback(struct urb *urb)
965{ 929{
930 struct si470x_device *radio = urb->context;
931 unsigned char buf[RDS_REPORT_SIZE];
932 int retval;
933 unsigned char regnr;
966 unsigned char blocknum; 934 unsigned char blocknum;
967 unsigned short bler; /* rds block errors */ 935 unsigned short bler; /* rds block errors */
968 unsigned short rds; 936 unsigned short rds;
969 unsigned char tmpbuf[3]; 937 unsigned char tmpbuf[3];
970 938
971 /* get rds blocks */ 939 if (urb->status) {
972 if (si470x_get_rds_registers(radio) < 0) 940 if (urb->status == -ENOENT ||
973 return; 941 urb->status == -ECONNRESET ||
974 if ((radio->registers[STATUSRSSI] & STATUSRSSI_RDSR) == 0) { 942 urb->status == -ESHUTDOWN) {
975 /* No RDS group ready */ 943 return;
976 return; 944 } else {
977 } 945 printk(KERN_WARNING DRIVER_NAME
978 if ((radio->registers[STATUSRSSI] & STATUSRSSI_RDSS) == 0) { 946 ": non-zero urb status (%d)\n", urb->status);
979 /* RDS decoder not synchronized */ 947 goto resubmit; /* Maybe we can recover. */
980 return;
981 }
982
983 /* copy all four RDS blocks to internal buffer */
984 mutex_lock(&radio->lock);
985 for (blocknum = 0; blocknum < 4; blocknum++) {
986 switch (blocknum) {
987 default:
988 bler = (radio->registers[STATUSRSSI] &
989 STATUSRSSI_BLERA) >> 9;
990 rds = radio->registers[RDSA];
991 break;
992 case 1:
993 bler = (radio->registers[READCHAN] &
994 READCHAN_BLERB) >> 14;
995 rds = radio->registers[RDSB];
996 break;
997 case 2:
998 bler = (radio->registers[READCHAN] &
999 READCHAN_BLERC) >> 12;
1000 rds = radio->registers[RDSC];
1001 break;
1002 case 3:
1003 bler = (radio->registers[READCHAN] &
1004 READCHAN_BLERD) >> 10;
1005 rds = radio->registers[RDSD];
1006 break;
1007 };
1008
1009 /* Fill the V4L2 RDS buffer */
1010 put_unaligned_le16(rds, &tmpbuf);
1011 tmpbuf[2] = blocknum; /* offset name */
1012 tmpbuf[2] |= blocknum << 3; /* received offset */
1013 if (bler > max_rds_errors)
1014 tmpbuf[2] |= 0x80; /* uncorrectable errors */
1015 else if (bler > 0)
1016 tmpbuf[2] |= 0x40; /* corrected error(s) */
1017
1018 /* copy RDS block to internal buffer */
1019 memcpy(&radio->buffer[radio->wr_index], &tmpbuf, 3);
1020 radio->wr_index += 3;
1021
1022 /* wrap write pointer */
1023 if (radio->wr_index >= radio->buf_size)
1024 radio->wr_index = 0;
1025
1026 /* check for overflow */
1027 if (radio->wr_index == radio->rd_index) {
1028 /* increment and wrap read pointer */
1029 radio->rd_index += 3;
1030 if (radio->rd_index >= radio->buf_size)
1031 radio->rd_index = 0;
1032 } 948 }
1033 } 949 }
1034 mutex_unlock(&radio->lock);
1035
1036 /* wake up read queue */
1037 if (radio->wr_index != radio->rd_index)
1038 wake_up_interruptible(&radio->read_queue);
1039}
1040
1041
1042/*
1043 * si470x_work - rds work function
1044 */
1045static void si470x_work(struct work_struct *work)
1046{
1047 struct si470x_device *radio = container_of(work, struct si470x_device,
1048 work.work);
1049 950
1050 /* safety checks */ 951 /* safety checks */
1051 if (radio->disconnected) 952 if (radio->disconnected)
1052 return; 953 return;
1053 if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0) 954 if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0)
1054 return; 955 goto resubmit;
1055 956
1056 si470x_rds(radio); 957 if (urb->actual_length > 0) {
1057 schedule_delayed_work(&radio->work, msecs_to_jiffies(rds_poll_time)); 958 /* Update RDS registers with URB data */
959 buf[0] = RDS_REPORT;
960 for (regnr = 0; regnr < RDS_REGISTER_NUM; regnr++)
961 radio->registers[STATUSRSSI + regnr] =
962 get_unaligned_be16(&radio->int_in_buffer[
963 regnr * RADIO_REGISTER_SIZE + 1]);
964 /* get rds blocks */
965 if ((radio->registers[STATUSRSSI] & STATUSRSSI_RDSR) == 0) {
966 /* No RDS group ready, better luck next time */
967 goto resubmit;
968 }
969 if ((radio->registers[STATUSRSSI] & STATUSRSSI_RDSS) == 0) {
970 /* RDS decoder not synchronized */
971 goto resubmit;
972 }
973 for (blocknum = 0; blocknum < 4; blocknum++) {
974 switch (blocknum) {
975 default:
976 bler = (radio->registers[STATUSRSSI] &
977 STATUSRSSI_BLERA) >> 9;
978 rds = radio->registers[RDSA];
979 break;
980 case 1:
981 bler = (radio->registers[READCHAN] &
982 READCHAN_BLERB) >> 14;
983 rds = radio->registers[RDSB];
984 break;
985 case 2:
986 bler = (radio->registers[READCHAN] &
987 READCHAN_BLERC) >> 12;
988 rds = radio->registers[RDSC];
989 break;
990 case 3:
991 bler = (radio->registers[READCHAN] &
992 READCHAN_BLERD) >> 10;
993 rds = radio->registers[RDSD];
994 break;
995 };
996
997 /* Fill the V4L2 RDS buffer */
998 put_unaligned_le16(rds, &tmpbuf);
999 tmpbuf[2] = blocknum; /* offset name */
1000 tmpbuf[2] |= blocknum << 3; /* received offset */
1001 if (bler > max_rds_errors)
1002 tmpbuf[2] |= 0x80; /* uncorrectable errors */
1003 else if (bler > 0)
1004 tmpbuf[2] |= 0x40; /* corrected error(s) */
1005
1006 /* copy RDS block to internal buffer */
1007 memcpy(&radio->buffer[radio->wr_index], &tmpbuf, 3);
1008 radio->wr_index += 3;
1009
1010 /* wrap write pointer */
1011 if (radio->wr_index >= radio->buf_size)
1012 radio->wr_index = 0;
1013
1014 /* check for overflow */
1015 if (radio->wr_index == radio->rd_index) {
1016 /* increment and wrap read pointer */
1017 radio->rd_index += 3;
1018 if (radio->rd_index >= radio->buf_size)
1019 radio->rd_index = 0;
1020 }
1021 }
1022 if (radio->wr_index != radio->rd_index)
1023 wake_up_interruptible(&radio->read_queue);
1024 }
1025
1026resubmit:
1027 /* Resubmit if we're still running. */
1028 if (radio->int_in_running && radio->usbdev) {
1029 retval = usb_submit_urb(radio->int_in_urb, GFP_ATOMIC);
1030 if (retval) {
1031 printk(KERN_WARNING DRIVER_NAME
1032 ": resubmitting urb failed (%d)", retval);
1033 radio->int_in_running = 0;
1034 }
1035 }
1058} 1036}
1059 1037
1060 1038
@@ -1076,8 +1054,6 @@ static ssize_t si470x_fops_read(struct file *file, char __user *buf,
1076 /* switch on rds reception */ 1054 /* switch on rds reception */
1077 if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0) { 1055 if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0) {
1078 si470x_rds_on(radio); 1056 si470x_rds_on(radio);
1079 schedule_delayed_work(&radio->work,
1080 msecs_to_jiffies(rds_poll_time));
1081 } 1057 }
1082 1058
1083 /* block if no new data available */ 1059 /* block if no new data available */
@@ -1136,8 +1112,6 @@ static unsigned int si470x_fops_poll(struct file *file,
1136 /* switch on rds reception */ 1112 /* switch on rds reception */
1137 if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0) { 1113 if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0) {
1138 si470x_rds_on(radio); 1114 si470x_rds_on(radio);
1139 schedule_delayed_work(&radio->work,
1140 msecs_to_jiffies(rds_poll_time));
1141 } 1115 }
1142 1116
1143 poll_wait(file, &radio->read_queue, pts); 1117 poll_wait(file, &radio->read_queue, pts);
@@ -1167,11 +1141,37 @@ static int si470x_fops_open(struct file *file)
1167 goto done; 1141 goto done;
1168 } 1142 }
1169 1143
1144 printk(KERN_INFO DRIVER_NAME
1145 ": Opened radio (users now: %i)\n", radio->users);
1146
1170 if (radio->users == 1) { 1147 if (radio->users == 1) {
1171 /* start radio */ 1148 /* start radio */
1172 retval = si470x_start(radio); 1149 retval = si470x_start(radio);
1173 if (retval < 0) 1150 if (retval < 0) {
1174 usb_autopm_put_interface(radio->intf); 1151 usb_autopm_put_interface(radio->intf);
1152 goto done;
1153 }
1154 /* Initialize interrupt URB. */
1155 usb_fill_int_urb(radio->int_in_urb, radio->usbdev,
1156 usb_rcvintpipe(radio->usbdev,
1157 radio->int_in_endpoint->bEndpointAddress),
1158 radio->int_in_buffer,
1159 le16_to_cpu(radio->int_in_endpoint->wMaxPacketSize),
1160 si470x_int_in_callback,
1161 radio,
1162 radio->int_in_endpoint->bInterval);
1163
1164 radio->int_in_running = 1;
1165 mb();
1166
1167 retval = usb_submit_urb(radio->int_in_urb, GFP_KERNEL);
1168 if (retval) {
1169 printk(KERN_INFO DRIVER_NAME
1170 ": submitting int urb failed (%d)\n", retval);
1171 radio->int_in_running = 0;
1172 usb_autopm_put_interface(radio->intf);
1173 }
1174
1175 } 1175 }
1176 1176
1177done: 1177done:
@@ -1196,17 +1196,25 @@ static int si470x_fops_release(struct file *file)
1196 1196
1197 mutex_lock(&radio->disconnect_lock); 1197 mutex_lock(&radio->disconnect_lock);
1198 radio->users--; 1198 radio->users--;
1199 printk(KERN_INFO DRIVER_NAME
1200 ": Closed radio (remaining users:%i)\n", radio->users);
1199 if (radio->users == 0) { 1201 if (radio->users == 0) {
1202
1203 /* Shutdown Interrupt handler */
1204 if (radio->int_in_running) {
1205 radio->int_in_running = 0;
1206 if (radio->int_in_urb)
1207 usb_kill_urb(radio->int_in_urb);
1208 }
1209
1200 if (radio->disconnected) { 1210 if (radio->disconnected) {
1201 video_unregister_device(radio->videodev); 1211 video_unregister_device(radio->videodev);
1212 kfree(radio->int_in_buffer);
1202 kfree(radio->buffer); 1213 kfree(radio->buffer);
1203 kfree(radio); 1214 kfree(radio);
1204 goto unlock; 1215 goto unlock;
1205 } 1216 }
1206 1217
1207 /* stop rds reception */
1208 cancel_delayed_work_sync(&radio->work);
1209
1210 /* cancel read processes */ 1218 /* cancel read processes */
1211 wake_up_interruptible(&radio->read_queue); 1219 wake_up_interruptible(&radio->read_queue);
1212 1220
@@ -1657,7 +1665,9 @@ static int si470x_usb_driver_probe(struct usb_interface *intf,
1657 const struct usb_device_id *id) 1665 const struct usb_device_id *id)
1658{ 1666{
1659 struct si470x_device *radio; 1667 struct si470x_device *radio;
1660 int retval = 0; 1668 struct usb_host_interface *iface_desc;
1669 struct usb_endpoint_descriptor *endpoint;
1670 int i, int_end_size, retval = 0;
1661 1671
1662 /* private data allocation and initialization */ 1672 /* private data allocation and initialization */
1663 radio = kzalloc(sizeof(struct si470x_device), GFP_KERNEL); 1673 radio = kzalloc(sizeof(struct si470x_device), GFP_KERNEL);
@@ -1672,11 +1682,45 @@ static int si470x_usb_driver_probe(struct usb_interface *intf,
1672 mutex_init(&radio->disconnect_lock); 1682 mutex_init(&radio->disconnect_lock);
1673 mutex_init(&radio->lock); 1683 mutex_init(&radio->lock);
1674 1684
1685 iface_desc = intf->cur_altsetting;
1686
1687 /* Set up interrupt endpoint information. */
1688 for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
1689 endpoint = &iface_desc->endpoint[i].desc;
1690 if (((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) ==
1691 USB_DIR_IN) && ((endpoint->bmAttributes &
1692 USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT))
1693 radio->int_in_endpoint = endpoint;
1694 }
1695 if (!radio->int_in_endpoint) {
1696 printk(KERN_INFO DRIVER_NAME
1697 ": could not find interrupt in endpoint\n");
1698 retval = -EIO;
1699 goto err_radio;
1700 }
1701
1702 int_end_size = le16_to_cpu(radio->int_in_endpoint->wMaxPacketSize);
1703
1704 radio->int_in_buffer = kmalloc(int_end_size, GFP_KERNEL);
1705 if (!radio->int_in_buffer) {
1706 printk(KERN_INFO DRIVER_NAME
1707 "could not allocate int_in_buffer");
1708 retval = -ENOMEM;
1709 goto err_radio;
1710 }
1711
1712 radio->int_in_urb = usb_alloc_urb(0, GFP_KERNEL);
1713 if (!radio->int_in_urb) {
1714 printk(KERN_INFO DRIVER_NAME "could not allocate int_in_urb");
1715 retval = -ENOMEM;
1716 goto err_intbuffer;
1717 }
1718
1675 /* video device allocation and initialization */ 1719 /* video device allocation and initialization */
1676 radio->videodev = video_device_alloc(); 1720 radio->videodev = video_device_alloc();
1677 if (!radio->videodev) { 1721 if (!radio->videodev) {
1678 retval = -ENOMEM; 1722 retval = -ENOMEM;
1679 goto err_radio; 1723 goto err_intbuffer;
1680 } 1724 }
1681 memcpy(radio->videodev, &si470x_viddev_template, 1725 memcpy(radio->videodev, &si470x_viddev_template,
1682 sizeof(si470x_viddev_template)); 1726 sizeof(si470x_viddev_template));
@@ -1734,9 +1778,6 @@ static int si470x_usb_driver_probe(struct usb_interface *intf,
1734 radio->rd_index = 0; 1778 radio->rd_index = 0;
1735 init_waitqueue_head(&radio->read_queue); 1779 init_waitqueue_head(&radio->read_queue);
1736 1780
1737 /* prepare rds work function */
1738 INIT_DELAYED_WORK(&radio->work, si470x_work);
1739
1740 /* register video device */ 1781 /* register video device */
1741 retval = video_register_device(radio->videodev, VFL_TYPE_RADIO, radio_nr); 1782 retval = video_register_device(radio->videodev, VFL_TYPE_RADIO, radio_nr);
1742 if (retval) { 1783 if (retval) {
@@ -1751,6 +1792,8 @@ err_all:
1751 kfree(radio->buffer); 1792 kfree(radio->buffer);
1752err_video: 1793err_video:
1753 video_device_release(radio->videodev); 1794 video_device_release(radio->videodev);
1795err_intbuffer:
1796 kfree(radio->int_in_buffer);
1754err_radio: 1797err_radio:
1755 kfree(radio); 1798 kfree(radio);
1756err_initial: 1799err_initial:
@@ -1764,12 +1807,8 @@ err_initial:
1764static int si470x_usb_driver_suspend(struct usb_interface *intf, 1807static int si470x_usb_driver_suspend(struct usb_interface *intf,
1765 pm_message_t message) 1808 pm_message_t message)
1766{ 1809{
1767 struct si470x_device *radio = usb_get_intfdata(intf);
1768
1769 printk(KERN_INFO DRIVER_NAME ": suspending now...\n"); 1810 printk(KERN_INFO DRIVER_NAME ": suspending now...\n");
1770 1811
1771 cancel_delayed_work_sync(&radio->work);
1772
1773 return 0; 1812 return 0;
1774} 1813}
1775 1814
@@ -1779,16 +1818,8 @@ static int si470x_usb_driver_suspend(struct usb_interface *intf,
1779 */ 1818 */
1780static int si470x_usb_driver_resume(struct usb_interface *intf) 1819static int si470x_usb_driver_resume(struct usb_interface *intf)
1781{ 1820{
1782 struct si470x_device *radio = usb_get_intfdata(intf);
1783
1784 printk(KERN_INFO DRIVER_NAME ": resuming now...\n"); 1821 printk(KERN_INFO DRIVER_NAME ": resuming now...\n");
1785 1822
1786 mutex_lock(&radio->lock);
1787 if (radio->users && radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS)
1788 schedule_delayed_work(&radio->work,
1789 msecs_to_jiffies(rds_poll_time));
1790 mutex_unlock(&radio->lock);
1791
1792 return 0; 1823 return 0;
1793} 1824}
1794 1825
@@ -1802,12 +1833,15 @@ static void si470x_usb_driver_disconnect(struct usb_interface *intf)
1802 1833
1803 mutex_lock(&radio->disconnect_lock); 1834 mutex_lock(&radio->disconnect_lock);
1804 radio->disconnected = 1; 1835 radio->disconnected = 1;
1805 cancel_delayed_work_sync(&radio->work);
1806 usb_set_intfdata(intf, NULL); 1836 usb_set_intfdata(intf, NULL);
1807 if (radio->users == 0) { 1837 if (radio->users == 0) {
1808 /* set led to disconnect state */ 1838 /* set led to disconnect state */
1809 si470x_set_led_state(radio, BLINK_ORANGE_LED); 1839 si470x_set_led_state(radio, BLINK_ORANGE_LED);
1810 1840
1841 /* Free data structures. */
1842 usb_free_urb(radio->int_in_urb);
1843
1844 kfree(radio->int_in_buffer);
1811 video_unregister_device(radio->videodev); 1845 video_unregister_device(radio->videodev);
1812 kfree(radio->buffer); 1846 kfree(radio->buffer);
1813 kfree(radio); 1847 kfree(radio);