32 #define DRIVER_CARD "Silicon Labs Si470x FM Radio Receiver"
33 #define DRIVER_DESC "USB radio driver for Si470x FM Radio Receivers"
34 #define DRIVER_VERSION "1.0.10"
38 #include <linux/hid.h>
39 #include <linux/slab.h>
47 { USB_DEVICE_AND_INTERFACE_INFO(0x10c4, 0x818a,
USB_CLASS_HID, 0, 0) },
49 { USB_DEVICE_AND_INTERFACE_INFO(0x06e1, 0xa155,
USB_CLASS_HID, 0, 0) },
51 { USB_DEVICE_AND_INTERFACE_INFO(0x1b80, 0xd700,
USB_CLASS_HID, 0, 0) },
53 { USB_DEVICE_AND_INTERFACE_INFO(0x10c5, 0x819a,
USB_CLASS_HID, 0, 0) },
55 { USB_DEVICE_AND_INTERFACE_INFO(0x12cf, 0x7111,
USB_CLASS_HID, 0, 0) },
68 static int radio_nr = -1;
73 static unsigned int usb_timeout = 500;
78 static unsigned int rds_buf = 100;
83 static unsigned short max_rds_errors = 1;
100 #define REGISTER_REPORT_SIZE (RADIO_REGISTER_SIZE + 1)
101 #define REGISTER_REPORT(reg) ((reg) + 1)
105 #define ENTIRE_REPORT_SIZE (RADIO_REGISTER_NUM * RADIO_REGISTER_SIZE + 1)
106 #define ENTIRE_REPORT 17
110 #define RDS_REPORT_SIZE (RDS_REGISTER_NUM * RADIO_REGISTER_SIZE + 1)
111 #define RDS_REPORT 18
114 #define LED_REPORT_SIZE 3
115 #define LED_REPORT 19
118 #define STREAM_REPORT_SIZE 3
119 #define STREAM_REPORT 19
122 #define SCRATCH_PAGE_SIZE 63
123 #define SCRATCH_REPORT_SIZE (SCRATCH_PAGE_SIZE + 1)
124 #define SCRATCH_REPORT 20
127 #define WRITE_REPORT_SIZE 4
128 #define WRITE_REPORT 19
129 #define FLASH_REPORT_SIZE 64
130 #define FLASH_REPORT 20
131 #define CRC_REPORT_SIZE 3
132 #define CRC_REPORT 21
133 #define RESPONSE_REPORT_SIZE 2
134 #define RESPONSE_REPORT 22
138 #define UNUSED_REPORT 23
145 #define RADIO_SW_VERSION_NOT_BOOTLOADABLE 6
146 #define RADIO_SW_VERSION 1
147 #define RADIO_HW_VERSION 1
154 #define LED_COMMAND 0x35
156 #define NO_CHANGE_LED 0x00
157 #define ALL_COLOR_LED 0x01
158 #define BLINK_GREEN_LED 0x02
159 #define BLINK_RED_LED 0x04
160 #define BLINK_ORANGE_LED 0x10
161 #define SOLID_GREEN_LED 0x20
162 #define SOLID_RED_LED 0x40
163 #define SOLID_ORANGE_LED 0x80
170 #define STREAM_COMMAND 0x36
171 #define STREAM_VIDPID 0x00
172 #define STREAM_AUDIO 0xff
181 #define UNIQUE_BL_ID 0x34
184 #define FLASH_DATA_MASK 0x55
187 #define GET_SW_VERSION_COMMAND 0x00
188 #define SET_PAGE_COMMAND 0x01
189 #define ERASE_PAGE_COMMAND 0x02
190 #define WRITE_PAGE_COMMAND 0x03
191 #define CRC_ON_PAGE_COMMAND 0x04
192 #define READ_FLASH_BYTE_COMMAND 0x05
193 #define RESET_DEVICE_COMMAND 0x06
194 #define GET_HW_VERSION_COMMAND 0x07
198 #define COMMAND_OK 0x01
199 #define COMMAND_FAILED 0x02
200 #define COMMAND_PENDING 0x03
213 unsigned char *
report = (
unsigned char *) buf;
217 usb_rcvctrlpipe(radio->usbdev, 0),
221 buf, size, usb_timeout);
225 "si470x_get_report: usb_control_msg returned %d\n",
236 unsigned char *
report = (
unsigned char *) buf;
240 usb_sndctrlpipe(radio->usbdev, 0),
244 buf, size, usb_timeout);
248 "si470x_set_report: usb_control_msg returned %d\n",
264 retval = si470x_get_report(radio, (
void *) &buf,
sizeof(buf));
267 radio->
registers[regnr] = get_unaligned_be16(&buf[1]);
269 return (retval < 0) ? -
EINVAL : 0;
282 put_unaligned_be16(radio->
registers[regnr], &buf[1]);
284 retval = si470x_set_report(radio, (
void *) &buf,
sizeof(buf));
286 return (retval < 0) ? -
EINVAL : 0;
298 static int si470x_get_all_registers(
struct si470x_device *radio)
306 retval = si470x_get_report(radio, (
void *) &buf,
sizeof(buf));
310 radio->
registers[regnr] = get_unaligned_be16(
313 return (retval < 0) ? -
EINVAL : 0;
335 retval = si470x_set_report(radio, (
void *) &buf,
sizeof(buf));
337 return (retval < 0) ? -
EINVAL : 0;
349 static int si470x_get_scratch_page_versions(
struct si470x_device *radio)
356 retval = si470x_get_report(radio, (
void *) &buf,
sizeof(buf));
359 dev_warn(&radio->intf->dev,
"si470x_get_scratch: "
360 "si470x_get_report returned %d\n", retval);
362 radio->software_version = buf[1];
363 radio->hardware_version = buf[2];
366 return (retval < 0) ? -
EINVAL : 0;
380 static void si470x_int_in_callback(
struct urb *
urb)
385 unsigned char blocknum;
391 if (urb->status == -
ENOENT ||
397 "non-zero urb status (%d)\n", urb->status);
407 get_unaligned_be16(&radio->int_in_buffer[1]);
416 get_unaligned_be16(&radio->int_in_buffer[
427 for (blocknum = 0; blocknum < 4; blocknum++) {
452 put_unaligned_le16(rds, &tmpbuf);
453 tmpbuf[2] = blocknum;
454 tmpbuf[2] |= blocknum << 3;
455 if (bler > max_rds_errors)
482 if (radio->int_in_running && radio->usbdev) {
486 "resubmitting urb failed (%d)", retval);
487 radio->int_in_running = 0;
512 kfree(radio->int_in_buffer);
532 usb_make_path(radio->usbdev, capability->
bus_info,
546 usb_fill_int_urb(radio->int_in_urb, radio->usbdev,
547 usb_rcvintpipe(radio->usbdev,
548 radio->int_in_endpoint->bEndpointAddress),
549 radio->int_in_buffer,
550 le16_to_cpu(radio->int_in_endpoint->wMaxPacketSize),
551 si470x_int_in_callback,
553 radio->int_in_endpoint->bInterval);
555 radio->int_in_running = 1;
561 "submitting int urb failed (%d)\n", retval);
562 radio->int_in_running = 0;
587 struct usb_host_interface *iface_desc;
589 int i, int_end_size, retval = 0;
590 unsigned char version_warning = 0;
598 radio->usbdev = interface_to_usbdev(intf);
604 iface_desc = intf->cur_altsetting;
607 for (i = 0; i < iface_desc->desc.bNumEndpoints; ++
i) {
608 endpoint = &iface_desc->endpoint[
i].desc;
612 radio->int_in_endpoint = endpoint;
614 if (!radio->int_in_endpoint) {
615 dev_info(&intf->dev,
"could not find interrupt in endpoint\n");
620 int_end_size =
le16_to_cpu(radio->int_in_endpoint->wMaxPacketSize);
623 if (!radio->int_in_buffer) {
624 dev_info(&intf->dev,
"could not allocate int_in_buffer");
630 if (!radio->int_in_urb) {
631 dev_info(&intf->dev,
"could not allocate int_in_urb");
636 radio->
v4l2_dev.release = si470x_usb_release;
639 dev_err(&intf->dev,
"couldn't register v4l2_device\n");
648 if (radio->
hdl.error) {
649 retval = radio->
hdl.error;
650 dev_err(&intf->dev,
"couldn't register control\n");
659 video_set_drvdata(&radio->
videodev, radio);
662 if (si470x_get_all_registers(radio) < 0) {
666 dev_info(&intf->dev,
"DeviceID=0x%4.4hx ChipID=0x%4.4hx\n",
670 "This driver is known to work with "
673 "but the device has firmware version %hu.\n",
679 if (si470x_get_scratch_page_versions(radio) < 0) {
683 dev_info(&intf->dev,
"software version %d, hardware version %d\n",
684 radio->software_version, radio->hardware_version);
687 "This driver is known to work with "
690 "but the device has software version %hu.\n",
691 radio->software_version);
696 "This driver is known to work with "
699 "but the device has hardware version %hu.\n",
700 radio->hardware_version);
705 if (version_warning == 1) {
707 "If you have some trouble using this driver,\n");
709 "please report to V4L ML at "
728 usb_set_intfdata(intf, radio);
731 retval = si470x_start_usb(radio);
742 dev_err(&intf->dev,
"Could not register video device\n");
756 kfree(radio->int_in_buffer);
767 static int si470x_usb_driver_suspend(
struct usb_interface *intf,
772 dev_info(&intf->dev,
"suspending now...\n");
775 if (radio->int_in_running) {
776 radio->int_in_running = 0;
777 if (radio->int_in_urb)
793 static int si470x_usb_driver_resume(
struct usb_interface *intf)
798 dev_info(&intf->dev,
"resuming now...\n");
801 ret = si470x_start_usb(radio);
812 static void si470x_usb_driver_disconnect(
struct usb_interface *intf)
819 usb_set_intfdata(intf,
NULL);
834 static struct usb_driver si470x_usb_driver = {
836 .probe = si470x_usb_driver_probe,
837 .disconnect = si470x_usb_driver_disconnect,
838 .suspend = si470x_usb_driver_suspend,
839 .resume = si470x_usb_driver_resume,
840 .reset_resume = si470x_usb_driver_resume,
841 .id_table = si470x_usb_driver_id_table,