xref: /openbmc/linux/drivers/media/radio/si470x/radio-si470x-usb.c (revision df2634f43f5106947f3735a0b61a6527a4b278cd)
1 /*
2  *  drivers/media/radio/si470x/radio-si470x-usb.c
3  *
4  *  USB driver for radios with Silicon Labs Si470x FM Radio Receivers
5  *
6  *  Copyright (c) 2009 Tobias Lorenz <tobias.lorenz@gmx.net>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21  */
22 
23 
24 /*
25  * ToDo:
26  * - add firmware download/update support
27  */
28 
29 
30 /* driver definitions */
31 #define DRIVER_AUTHOR "Tobias Lorenz <tobias.lorenz@gmx.net>"
32 #define DRIVER_KERNEL_VERSION KERNEL_VERSION(1, 0, 10)
33 #define DRIVER_CARD "Silicon Labs Si470x FM Radio Receiver"
34 #define DRIVER_DESC "USB radio driver for Si470x FM Radio Receivers"
35 #define DRIVER_VERSION "1.0.10"
36 
37 /* kernel includes */
38 #include <linux/usb.h>
39 #include <linux/hid.h>
40 #include <linux/slab.h>
41 
42 #include "radio-si470x.h"
43 
44 
45 /* USB Device ID List */
46 static struct usb_device_id si470x_usb_driver_id_table[] = {
47 	/* Silicon Labs USB FM Radio Reference Design */
48 	{ USB_DEVICE_AND_INTERFACE_INFO(0x10c4, 0x818a, USB_CLASS_HID, 0, 0) },
49 	/* ADS/Tech FM Radio Receiver (formerly Instant FM Music) */
50 	{ USB_DEVICE_AND_INTERFACE_INFO(0x06e1, 0xa155, USB_CLASS_HID, 0, 0) },
51 	/* KWorld USB FM Radio SnapMusic Mobile 700 (FM700) */
52 	{ USB_DEVICE_AND_INTERFACE_INFO(0x1b80, 0xd700, USB_CLASS_HID, 0, 0) },
53 	/* Sanei Electric, Inc. FM USB Radio (sold as DealExtreme.com PCear) */
54 	{ USB_DEVICE_AND_INTERFACE_INFO(0x10c5, 0x819a, USB_CLASS_HID, 0, 0) },
55 	/* Terminating entry */
56 	{ }
57 };
58 MODULE_DEVICE_TABLE(usb, si470x_usb_driver_id_table);
59 
60 
61 
62 /**************************************************************************
63  * Module Parameters
64  **************************************************************************/
65 
66 /* Radio Nr */
67 static int radio_nr = -1;
68 module_param(radio_nr, int, 0444);
69 MODULE_PARM_DESC(radio_nr, "Radio Nr");
70 
71 /* USB timeout */
72 static unsigned int usb_timeout = 500;
73 module_param(usb_timeout, uint, 0644);
74 MODULE_PARM_DESC(usb_timeout, "USB timeout (ms): *500*");
75 
76 /* RDS buffer blocks */
77 static unsigned int rds_buf = 100;
78 module_param(rds_buf, uint, 0444);
79 MODULE_PARM_DESC(rds_buf, "RDS buffer entries: *100*");
80 
81 /* RDS maximum block errors */
82 static unsigned short max_rds_errors = 1;
83 /* 0 means   0  errors requiring correction */
84 /* 1 means 1-2  errors requiring correction (used by original USBRadio.exe) */
85 /* 2 means 3-5  errors requiring correction */
86 /* 3 means   6+ errors or errors in checkword, correction not possible */
87 module_param(max_rds_errors, ushort, 0644);
88 MODULE_PARM_DESC(max_rds_errors, "RDS maximum block errors: *1*");
89 
90 
91 
92 /**************************************************************************
93  * USB HID Reports
94  **************************************************************************/
95 
96 /* Reports 1-16 give direct read/write access to the 16 Si470x registers */
97 /* with the (REPORT_ID - 1) corresponding to the register address across USB */
98 /* endpoint 0 using GET_REPORT and SET_REPORT */
99 #define REGISTER_REPORT_SIZE	(RADIO_REGISTER_SIZE + 1)
100 #define REGISTER_REPORT(reg)	((reg) + 1)
101 
102 /* Report 17 gives direct read/write access to the entire Si470x register */
103 /* map across endpoint 0 using GET_REPORT and SET_REPORT */
104 #define ENTIRE_REPORT_SIZE	(RADIO_REGISTER_NUM * RADIO_REGISTER_SIZE + 1)
105 #define ENTIRE_REPORT		17
106 
107 /* Report 18 is used to send the lowest 6 Si470x registers up the HID */
108 /* interrupt endpoint 1 to Windows every 20 milliseconds for status */
109 #define RDS_REPORT_SIZE		(RDS_REGISTER_NUM * RADIO_REGISTER_SIZE + 1)
110 #define RDS_REPORT		18
111 
112 /* Report 19: LED state */
113 #define LED_REPORT_SIZE		3
114 #define LED_REPORT		19
115 
116 /* Report 19: stream */
117 #define STREAM_REPORT_SIZE	3
118 #define STREAM_REPORT		19
119 
120 /* Report 20: scratch */
121 #define SCRATCH_PAGE_SIZE	63
122 #define SCRATCH_REPORT_SIZE	(SCRATCH_PAGE_SIZE + 1)
123 #define SCRATCH_REPORT		20
124 
125 /* Reports 19-22: flash upgrade of the C8051F321 */
126 #define WRITE_REPORT_SIZE	4
127 #define WRITE_REPORT		19
128 #define FLASH_REPORT_SIZE	64
129 #define FLASH_REPORT		20
130 #define CRC_REPORT_SIZE		3
131 #define CRC_REPORT		21
132 #define RESPONSE_REPORT_SIZE	2
133 #define RESPONSE_REPORT		22
134 
135 /* Report 23: currently unused, but can accept 60 byte reports on the HID */
136 /* interrupt out endpoint 2 every 1 millisecond */
137 #define UNUSED_REPORT		23
138 
139 
140 
141 /**************************************************************************
142  * Software/Hardware Versions from Scratch Page
143  **************************************************************************/
144 #define RADIO_SW_VERSION_NOT_BOOTLOADABLE	6
145 #define RADIO_SW_VERSION			7
146 #define RADIO_HW_VERSION			1
147 
148 
149 
150 /**************************************************************************
151  * LED State Definitions
152  **************************************************************************/
153 #define LED_COMMAND		0x35
154 
155 #define NO_CHANGE_LED		0x00
156 #define ALL_COLOR_LED		0x01	/* streaming state */
157 #define BLINK_GREEN_LED		0x02	/* connect state */
158 #define BLINK_RED_LED		0x04
159 #define BLINK_ORANGE_LED	0x10	/* disconnect state */
160 #define SOLID_GREEN_LED		0x20	/* tuning/seeking state */
161 #define SOLID_RED_LED		0x40	/* bootload state */
162 #define SOLID_ORANGE_LED	0x80
163 
164 
165 
166 /**************************************************************************
167  * Stream State Definitions
168  **************************************************************************/
169 #define STREAM_COMMAND	0x36
170 #define STREAM_VIDPID	0x00
171 #define STREAM_AUDIO	0xff
172 
173 
174 
175 /**************************************************************************
176  * Bootloader / Flash Commands
177  **************************************************************************/
178 
179 /* unique id sent to bootloader and required to put into a bootload state */
180 #define UNIQUE_BL_ID		0x34
181 
182 /* mask for the flash data */
183 #define FLASH_DATA_MASK		0x55
184 
185 /* bootloader commands */
186 #define GET_SW_VERSION_COMMAND	0x00
187 #define SET_PAGE_COMMAND	0x01
188 #define ERASE_PAGE_COMMAND	0x02
189 #define WRITE_PAGE_COMMAND	0x03
190 #define CRC_ON_PAGE_COMMAND	0x04
191 #define READ_FLASH_BYTE_COMMAND	0x05
192 #define RESET_DEVICE_COMMAND	0x06
193 #define GET_HW_VERSION_COMMAND	0x07
194 #define BLANK			0xff
195 
196 /* bootloader command responses */
197 #define COMMAND_OK		0x01
198 #define COMMAND_FAILED		0x02
199 #define COMMAND_PENDING		0x03
200 
201 
202 
203 /**************************************************************************
204  * General Driver Functions - REGISTER_REPORTs
205  **************************************************************************/
206 
207 /*
208  * si470x_get_report - receive a HID report
209  */
210 static int si470x_get_report(struct si470x_device *radio, void *buf, int size)
211 {
212 	unsigned char *report = (unsigned char *) buf;
213 	int retval;
214 
215 	retval = usb_control_msg(radio->usbdev,
216 		usb_rcvctrlpipe(radio->usbdev, 0),
217 		HID_REQ_GET_REPORT,
218 		USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
219 		report[0], 2,
220 		buf, size, usb_timeout);
221 
222 	if (retval < 0)
223 		dev_warn(&radio->intf->dev,
224 			"si470x_get_report: usb_control_msg returned %d\n",
225 			retval);
226 	return retval;
227 }
228 
229 
230 /*
231  * si470x_set_report - send a HID report
232  */
233 static int si470x_set_report(struct si470x_device *radio, void *buf, int size)
234 {
235 	unsigned char *report = (unsigned char *) buf;
236 	int retval;
237 
238 	retval = usb_control_msg(radio->usbdev,
239 		usb_sndctrlpipe(radio->usbdev, 0),
240 		HID_REQ_SET_REPORT,
241 		USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
242 		report[0], 2,
243 		buf, size, usb_timeout);
244 
245 	if (retval < 0)
246 		dev_warn(&radio->intf->dev,
247 			"si470x_set_report: usb_control_msg returned %d\n",
248 			retval);
249 	return retval;
250 }
251 
252 
253 /*
254  * si470x_get_register - read register
255  */
256 int si470x_get_register(struct si470x_device *radio, int regnr)
257 {
258 	unsigned char buf[REGISTER_REPORT_SIZE];
259 	int retval;
260 
261 	buf[0] = REGISTER_REPORT(regnr);
262 
263 	retval = si470x_get_report(radio, (void *) &buf, sizeof(buf));
264 
265 	if (retval >= 0)
266 		radio->registers[regnr] = get_unaligned_be16(&buf[1]);
267 
268 	return (retval < 0) ? -EINVAL : 0;
269 }
270 
271 
272 /*
273  * si470x_set_register - write register
274  */
275 int si470x_set_register(struct si470x_device *radio, int regnr)
276 {
277 	unsigned char buf[REGISTER_REPORT_SIZE];
278 	int retval;
279 
280 	buf[0] = REGISTER_REPORT(regnr);
281 	put_unaligned_be16(radio->registers[regnr], &buf[1]);
282 
283 	retval = si470x_set_report(radio, (void *) &buf, sizeof(buf));
284 
285 	return (retval < 0) ? -EINVAL : 0;
286 }
287 
288 
289 
290 /**************************************************************************
291  * General Driver Functions - ENTIRE_REPORT
292  **************************************************************************/
293 
294 /*
295  * si470x_get_all_registers - read entire registers
296  */
297 static int si470x_get_all_registers(struct si470x_device *radio)
298 {
299 	unsigned char buf[ENTIRE_REPORT_SIZE];
300 	int retval;
301 	unsigned char regnr;
302 
303 	buf[0] = ENTIRE_REPORT;
304 
305 	retval = si470x_get_report(radio, (void *) &buf, sizeof(buf));
306 
307 	if (retval >= 0)
308 		for (regnr = 0; regnr < RADIO_REGISTER_NUM; regnr++)
309 			radio->registers[regnr] = get_unaligned_be16(
310 				&buf[regnr * RADIO_REGISTER_SIZE + 1]);
311 
312 	return (retval < 0) ? -EINVAL : 0;
313 }
314 
315 
316 
317 /**************************************************************************
318  * General Driver Functions - LED_REPORT
319  **************************************************************************/
320 
321 /*
322  * si470x_set_led_state - sets the led state
323  */
324 static int si470x_set_led_state(struct si470x_device *radio,
325 		unsigned char led_state)
326 {
327 	unsigned char buf[LED_REPORT_SIZE];
328 	int retval;
329 
330 	buf[0] = LED_REPORT;
331 	buf[1] = LED_COMMAND;
332 	buf[2] = led_state;
333 
334 	retval = si470x_set_report(radio, (void *) &buf, sizeof(buf));
335 
336 	return (retval < 0) ? -EINVAL : 0;
337 }
338 
339 
340 
341 /**************************************************************************
342  * General Driver Functions - SCRATCH_REPORT
343  **************************************************************************/
344 
345 /*
346  * si470x_get_scratch_versions - gets the scratch page and version infos
347  */
348 static int si470x_get_scratch_page_versions(struct si470x_device *radio)
349 {
350 	unsigned char buf[SCRATCH_REPORT_SIZE];
351 	int retval;
352 
353 	buf[0] = SCRATCH_REPORT;
354 
355 	retval = si470x_get_report(radio, (void *) &buf, sizeof(buf));
356 
357 	if (retval < 0)
358 		dev_warn(&radio->intf->dev, "si470x_get_scratch: "
359 			"si470x_get_report returned %d\n", retval);
360 	else {
361 		radio->software_version = buf[1];
362 		radio->hardware_version = buf[2];
363 	}
364 
365 	return (retval < 0) ? -EINVAL : 0;
366 }
367 
368 
369 
370 /**************************************************************************
371  * General Driver Functions - DISCONNECT_CHECK
372  **************************************************************************/
373 
374 /*
375  * si470x_disconnect_check - check whether radio disconnects
376  */
377 int si470x_disconnect_check(struct si470x_device *radio)
378 {
379 	if (radio->disconnected)
380 		return -EIO;
381 	else
382 		return 0;
383 }
384 
385 
386 
387 /**************************************************************************
388  * RDS Driver Functions
389  **************************************************************************/
390 
391 /*
392  * si470x_int_in_callback - rds callback and processing function
393  *
394  * TODO: do we need to use mutex locks in some sections?
395  */
396 static void si470x_int_in_callback(struct urb *urb)
397 {
398 	struct si470x_device *radio = urb->context;
399 	unsigned char buf[RDS_REPORT_SIZE];
400 	int retval;
401 	unsigned char regnr;
402 	unsigned char blocknum;
403 	unsigned short bler; /* rds block errors */
404 	unsigned short rds;
405 	unsigned char tmpbuf[3];
406 
407 	if (urb->status) {
408 		if (urb->status == -ENOENT ||
409 				urb->status == -ECONNRESET ||
410 				urb->status == -ESHUTDOWN) {
411 			return;
412 		} else {
413 			dev_warn(&radio->intf->dev,
414 			 "non-zero urb status (%d)\n", urb->status);
415 			goto resubmit; /* Maybe we can recover. */
416 		}
417 	}
418 
419 	/* safety checks */
420 	if (radio->disconnected)
421 		return;
422 	if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0)
423 		goto resubmit;
424 
425 	if (urb->actual_length > 0) {
426 		/* Update RDS registers with URB data */
427 		buf[0] = RDS_REPORT;
428 		for (regnr = 0; regnr < RDS_REGISTER_NUM; regnr++)
429 			radio->registers[STATUSRSSI + regnr] =
430 			    get_unaligned_be16(&radio->int_in_buffer[
431 				regnr * RADIO_REGISTER_SIZE + 1]);
432 		/* get rds blocks */
433 		if ((radio->registers[STATUSRSSI] & STATUSRSSI_RDSR) == 0) {
434 			/* No RDS group ready, better luck next time */
435 			goto resubmit;
436 		}
437 		if ((radio->registers[STATUSRSSI] & STATUSRSSI_RDSS) == 0) {
438 			/* RDS decoder not synchronized */
439 			goto resubmit;
440 		}
441 		for (blocknum = 0; blocknum < 4; blocknum++) {
442 			switch (blocknum) {
443 			default:
444 				bler = (radio->registers[STATUSRSSI] &
445 						STATUSRSSI_BLERA) >> 9;
446 				rds = radio->registers[RDSA];
447 				break;
448 			case 1:
449 				bler = (radio->registers[READCHAN] &
450 						READCHAN_BLERB) >> 14;
451 				rds = radio->registers[RDSB];
452 				break;
453 			case 2:
454 				bler = (radio->registers[READCHAN] &
455 						READCHAN_BLERC) >> 12;
456 				rds = radio->registers[RDSC];
457 				break;
458 			case 3:
459 				bler = (radio->registers[READCHAN] &
460 						READCHAN_BLERD) >> 10;
461 				rds = radio->registers[RDSD];
462 				break;
463 			};
464 
465 			/* Fill the V4L2 RDS buffer */
466 			put_unaligned_le16(rds, &tmpbuf);
467 			tmpbuf[2] = blocknum;		/* offset name */
468 			tmpbuf[2] |= blocknum << 3;	/* received offset */
469 			if (bler > max_rds_errors)
470 				tmpbuf[2] |= 0x80; /* uncorrectable errors */
471 			else if (bler > 0)
472 				tmpbuf[2] |= 0x40; /* corrected error(s) */
473 
474 			/* copy RDS block to internal buffer */
475 			memcpy(&radio->buffer[radio->wr_index], &tmpbuf, 3);
476 			radio->wr_index += 3;
477 
478 			/* wrap write pointer */
479 			if (radio->wr_index >= radio->buf_size)
480 				radio->wr_index = 0;
481 
482 			/* check for overflow */
483 			if (radio->wr_index == radio->rd_index) {
484 				/* increment and wrap read pointer */
485 				radio->rd_index += 3;
486 				if (radio->rd_index >= radio->buf_size)
487 					radio->rd_index = 0;
488 			}
489 		}
490 		if (radio->wr_index != radio->rd_index)
491 			wake_up_interruptible(&radio->read_queue);
492 	}
493 
494 resubmit:
495 	/* Resubmit if we're still running. */
496 	if (radio->int_in_running && radio->usbdev) {
497 		retval = usb_submit_urb(radio->int_in_urb, GFP_ATOMIC);
498 		if (retval) {
499 			dev_warn(&radio->intf->dev,
500 			       "resubmitting urb failed (%d)", retval);
501 			radio->int_in_running = 0;
502 		}
503 	}
504 }
505 
506 
507 
508 /**************************************************************************
509  * File Operations Interface
510  **************************************************************************/
511 
512 /*
513  * si470x_fops_open - file open
514  */
515 int si470x_fops_open(struct file *file)
516 {
517 	struct si470x_device *radio = video_drvdata(file);
518 	int retval;
519 
520 	mutex_lock(&radio->lock);
521 	radio->users++;
522 
523 	retval = usb_autopm_get_interface(radio->intf);
524 	if (retval < 0) {
525 		radio->users--;
526 		retval = -EIO;
527 		goto done;
528 	}
529 
530 	if (radio->users == 1) {
531 		/* start radio */
532 		retval = si470x_start(radio);
533 		if (retval < 0) {
534 			usb_autopm_put_interface(radio->intf);
535 			goto done;
536 		}
537 
538 		/* initialize interrupt urb */
539 		usb_fill_int_urb(radio->int_in_urb, radio->usbdev,
540 			usb_rcvintpipe(radio->usbdev,
541 			radio->int_in_endpoint->bEndpointAddress),
542 			radio->int_in_buffer,
543 			le16_to_cpu(radio->int_in_endpoint->wMaxPacketSize),
544 			si470x_int_in_callback,
545 			radio,
546 			radio->int_in_endpoint->bInterval);
547 
548 		radio->int_in_running = 1;
549 		mb();
550 
551 		retval = usb_submit_urb(radio->int_in_urb, GFP_KERNEL);
552 		if (retval) {
553 			dev_info(&radio->intf->dev,
554 				 "submitting int urb failed (%d)\n", retval);
555 			radio->int_in_running = 0;
556 			usb_autopm_put_interface(radio->intf);
557 		}
558 	}
559 
560 done:
561 	mutex_unlock(&radio->lock);
562 	return retval;
563 }
564 
565 
566 /*
567  * si470x_fops_release - file release
568  */
569 int si470x_fops_release(struct file *file)
570 {
571 	struct si470x_device *radio = video_drvdata(file);
572 	int retval = 0;
573 
574 	/* safety check */
575 	if (!radio) {
576 		retval = -ENODEV;
577 		goto done;
578 	}
579 
580 	mutex_lock(&radio->lock);
581 	radio->users--;
582 	if (radio->users == 0) {
583 		/* shutdown interrupt handler */
584 		if (radio->int_in_running) {
585 			radio->int_in_running = 0;
586 		if (radio->int_in_urb)
587 			usb_kill_urb(radio->int_in_urb);
588 		}
589 
590 		if (radio->disconnected) {
591 			video_unregister_device(radio->videodev);
592 			kfree(radio->int_in_buffer);
593 			kfree(radio->buffer);
594 			mutex_unlock(&radio->lock);
595 			kfree(radio);
596 			goto done;
597 		}
598 
599 		/* cancel read processes */
600 		wake_up_interruptible(&radio->read_queue);
601 
602 		/* stop radio */
603 		retval = si470x_stop(radio);
604 		usb_autopm_put_interface(radio->intf);
605 	}
606 	mutex_unlock(&radio->lock);
607 done:
608 	return retval;
609 }
610 
611 
612 
613 /**************************************************************************
614  * Video4Linux Interface
615  **************************************************************************/
616 
617 /*
618  * si470x_vidioc_querycap - query device capabilities
619  */
620 int si470x_vidioc_querycap(struct file *file, void *priv,
621 		struct v4l2_capability *capability)
622 {
623 	struct si470x_device *radio = video_drvdata(file);
624 
625 	strlcpy(capability->driver, DRIVER_NAME, sizeof(capability->driver));
626 	strlcpy(capability->card, DRIVER_CARD, sizeof(capability->card));
627 	usb_make_path(radio->usbdev, capability->bus_info,
628 			sizeof(capability->bus_info));
629 	capability->version = DRIVER_KERNEL_VERSION;
630 	capability->capabilities = V4L2_CAP_HW_FREQ_SEEK |
631 		V4L2_CAP_TUNER | V4L2_CAP_RADIO | V4L2_CAP_RDS_CAPTURE;
632 
633 	return 0;
634 }
635 
636 
637 
638 /**************************************************************************
639  * USB Interface
640  **************************************************************************/
641 
642 /*
643  * si470x_usb_driver_probe - probe for the device
644  */
645 static int si470x_usb_driver_probe(struct usb_interface *intf,
646 		const struct usb_device_id *id)
647 {
648 	struct si470x_device *radio;
649 	struct usb_host_interface *iface_desc;
650 	struct usb_endpoint_descriptor *endpoint;
651 	int i, int_end_size, retval = 0;
652 	unsigned char version_warning = 0;
653 
654 	/* private data allocation and initialization */
655 	radio = kzalloc(sizeof(struct si470x_device), GFP_KERNEL);
656 	if (!radio) {
657 		retval = -ENOMEM;
658 		goto err_initial;
659 	}
660 	radio->users = 0;
661 	radio->disconnected = 0;
662 	radio->usbdev = interface_to_usbdev(intf);
663 	radio->intf = intf;
664 	mutex_init(&radio->lock);
665 
666 	iface_desc = intf->cur_altsetting;
667 
668 	/* Set up interrupt endpoint information. */
669 	for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
670 		endpoint = &iface_desc->endpoint[i].desc;
671 		if (((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) ==
672 		 USB_DIR_IN) && ((endpoint->bmAttributes &
673 		 USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT))
674 			radio->int_in_endpoint = endpoint;
675 	}
676 	if (!radio->int_in_endpoint) {
677 		dev_info(&intf->dev, "could not find interrupt in endpoint\n");
678 		retval = -EIO;
679 		goto err_radio;
680 	}
681 
682 	int_end_size = le16_to_cpu(radio->int_in_endpoint->wMaxPacketSize);
683 
684 	radio->int_in_buffer = kmalloc(int_end_size, GFP_KERNEL);
685 	if (!radio->int_in_buffer) {
686 		dev_info(&intf->dev, "could not allocate int_in_buffer");
687 		retval = -ENOMEM;
688 		goto err_radio;
689 	}
690 
691 	radio->int_in_urb = usb_alloc_urb(0, GFP_KERNEL);
692 	if (!radio->int_in_urb) {
693 		dev_info(&intf->dev, "could not allocate int_in_urb");
694 		retval = -ENOMEM;
695 		goto err_intbuffer;
696 	}
697 
698 	/* video device allocation and initialization */
699 	radio->videodev = video_device_alloc();
700 	if (!radio->videodev) {
701 		retval = -ENOMEM;
702 		goto err_intbuffer;
703 	}
704 	memcpy(radio->videodev, &si470x_viddev_template,
705 			sizeof(si470x_viddev_template));
706 	video_set_drvdata(radio->videodev, radio);
707 
708 	/* get device and chip versions */
709 	if (si470x_get_all_registers(radio) < 0) {
710 		retval = -EIO;
711 		goto err_video;
712 	}
713 	dev_info(&intf->dev, "DeviceID=0x%4.4hx ChipID=0x%4.4hx\n",
714 			radio->registers[DEVICEID], radio->registers[CHIPID]);
715 	if ((radio->registers[CHIPID] & CHIPID_FIRMWARE) < RADIO_FW_VERSION) {
716 		dev_warn(&intf->dev,
717 			"This driver is known to work with "
718 			"firmware version %hu,\n", RADIO_FW_VERSION);
719 		dev_warn(&intf->dev,
720 			"but the device has firmware version %hu.\n",
721 			radio->registers[CHIPID] & CHIPID_FIRMWARE);
722 		version_warning = 1;
723 	}
724 
725 	/* get software and hardware versions */
726 	if (si470x_get_scratch_page_versions(radio) < 0) {
727 		retval = -EIO;
728 		goto err_video;
729 	}
730 	dev_info(&intf->dev, "software version %d, hardware version %d\n",
731 			radio->software_version, radio->hardware_version);
732 	if (radio->software_version < RADIO_SW_VERSION) {
733 		dev_warn(&intf->dev,
734 			"This driver is known to work with "
735 			"software version %hu,\n", RADIO_SW_VERSION);
736 		dev_warn(&intf->dev,
737 			"but the device has software version %hu.\n",
738 			radio->software_version);
739 		version_warning = 1;
740 	}
741 	if (radio->hardware_version < RADIO_HW_VERSION) {
742 		dev_warn(&intf->dev,
743 			"This driver is known to work with "
744 			"hardware version %hu,\n", RADIO_HW_VERSION);
745 		dev_warn(&intf->dev,
746 			"but the device has hardware version %hu.\n",
747 			radio->hardware_version);
748 		version_warning = 1;
749 	}
750 
751 	/* give out version warning */
752 	if (version_warning == 1) {
753 		dev_warn(&intf->dev,
754 			"If you have some trouble using this driver,\n");
755 		dev_warn(&intf->dev,
756 			"please report to V4L ML at "
757 			"linux-media@vger.kernel.org\n");
758 	}
759 
760 	/* set initial frequency */
761 	si470x_set_freq(radio, 87.5 * FREQ_MUL); /* available in all regions */
762 
763 	/* set led to connect state */
764 	si470x_set_led_state(radio, BLINK_GREEN_LED);
765 
766 	/* rds buffer allocation */
767 	radio->buf_size = rds_buf * 3;
768 	radio->buffer = kmalloc(radio->buf_size, GFP_KERNEL);
769 	if (!radio->buffer) {
770 		retval = -EIO;
771 		goto err_video;
772 	}
773 
774 	/* rds buffer configuration */
775 	radio->wr_index = 0;
776 	radio->rd_index = 0;
777 	init_waitqueue_head(&radio->read_queue);
778 
779 	/* register video device */
780 	retval = video_register_device(radio->videodev, VFL_TYPE_RADIO,
781 			radio_nr);
782 	if (retval) {
783 		dev_warn(&intf->dev, "Could not register video device\n");
784 		goto err_all;
785 	}
786 	usb_set_intfdata(intf, radio);
787 
788 	return 0;
789 err_all:
790 	kfree(radio->buffer);
791 err_video:
792 	video_device_release(radio->videodev);
793 err_intbuffer:
794 	kfree(radio->int_in_buffer);
795 err_radio:
796 	kfree(radio);
797 err_initial:
798 	return retval;
799 }
800 
801 
802 /*
803  * si470x_usb_driver_suspend - suspend the device
804  */
805 static int si470x_usb_driver_suspend(struct usb_interface *intf,
806 		pm_message_t message)
807 {
808 	dev_info(&intf->dev, "suspending now...\n");
809 
810 	return 0;
811 }
812 
813 
814 /*
815  * si470x_usb_driver_resume - resume the device
816  */
817 static int si470x_usb_driver_resume(struct usb_interface *intf)
818 {
819 	dev_info(&intf->dev, "resuming now...\n");
820 
821 	return 0;
822 }
823 
824 
825 /*
826  * si470x_usb_driver_disconnect - disconnect the device
827  */
828 static void si470x_usb_driver_disconnect(struct usb_interface *intf)
829 {
830 	struct si470x_device *radio = usb_get_intfdata(intf);
831 
832 	mutex_lock(&radio->lock);
833 	radio->disconnected = 1;
834 	usb_set_intfdata(intf, NULL);
835 	if (radio->users == 0) {
836 		/* set led to disconnect state */
837 		si470x_set_led_state(radio, BLINK_ORANGE_LED);
838 
839 		/* Free data structures. */
840 		usb_free_urb(radio->int_in_urb);
841 
842 		kfree(radio->int_in_buffer);
843 		video_unregister_device(radio->videodev);
844 		kfree(radio->buffer);
845 		mutex_unlock(&radio->lock);
846 		kfree(radio);
847 	} else {
848 		mutex_unlock(&radio->lock);
849 	}
850 }
851 
852 
853 /*
854  * si470x_usb_driver - usb driver interface
855  */
856 static struct usb_driver si470x_usb_driver = {
857 	.name			= DRIVER_NAME,
858 	.probe			= si470x_usb_driver_probe,
859 	.disconnect		= si470x_usb_driver_disconnect,
860 	.suspend		= si470x_usb_driver_suspend,
861 	.resume			= si470x_usb_driver_resume,
862 	.id_table		= si470x_usb_driver_id_table,
863 	.supports_autosuspend	= 1,
864 };
865 
866 
867 
868 /**************************************************************************
869  * Module Interface
870  **************************************************************************/
871 
872 /*
873  * si470x_module_init - module init
874  */
875 static int __init si470x_module_init(void)
876 {
877 	printk(KERN_INFO DRIVER_DESC ", Version " DRIVER_VERSION "\n");
878 	return usb_register(&si470x_usb_driver);
879 }
880 
881 
882 /*
883  * si470x_module_exit - module exit
884  */
885 static void __exit si470x_module_exit(void)
886 {
887 	usb_deregister(&si470x_usb_driver);
888 }
889 
890 
891 module_init(si470x_module_init);
892 module_exit(si470x_module_exit);
893 
894 MODULE_LICENSE("GPL");
895 MODULE_AUTHOR(DRIVER_AUTHOR);
896 MODULE_DESCRIPTION(DRIVER_DESC);
897 MODULE_VERSION(DRIVER_VERSION);
898