aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/radio/radio-si470x.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/radio/radio-si470x.c')
-rw-r--r--drivers/media/radio/radio-si470x.c109
1 files changed, 75 insertions, 34 deletions
diff --git a/drivers/media/radio/radio-si470x.c b/drivers/media/radio/radio-si470x.c
index dfaaa467c043..9827445086aa 100644
--- a/drivers/media/radio/radio-si470x.c
+++ b/drivers/media/radio/radio-si470x.c
@@ -105,6 +105,7 @@
105 * 2009-01-31 Rick Bronson <rick@efn.org> 105 * 2009-01-31 Rick Bronson <rick@efn.org>
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 * 109 *
109 * ToDo: 110 * ToDo:
110 * - add firmware download/update support 111 * - add firmware download/update support
@@ -115,10 +116,10 @@
115/* driver definitions */ 116/* driver definitions */
116#define DRIVER_AUTHOR "Tobias Lorenz <tobias.lorenz@gmx.net>" 117#define DRIVER_AUTHOR "Tobias Lorenz <tobias.lorenz@gmx.net>"
117#define DRIVER_NAME "radio-si470x" 118#define DRIVER_NAME "radio-si470x"
118#define DRIVER_KERNEL_VERSION KERNEL_VERSION(1, 0, 8) 119#define DRIVER_KERNEL_VERSION KERNEL_VERSION(1, 0, 9)
119#define DRIVER_CARD "Silicon Labs Si470x FM Radio Receiver" 120#define DRIVER_CARD "Silicon Labs Si470x FM Radio Receiver"
120#define DRIVER_DESC "USB radio driver for Si470x FM Radio Receivers" 121#define DRIVER_DESC "USB radio driver for Si470x FM Radio Receivers"
121#define DRIVER_VERSION "1.0.8" 122#define DRIVER_VERSION "1.0.9"
122 123
123 124
124/* kernel includes */ 125/* kernel includes */
@@ -354,9 +355,13 @@ MODULE_PARM_DESC(rds_poll_time, "RDS poll time (ms): *40*");
354#define SCRATCH_REPORT 20 355#define SCRATCH_REPORT 20
355 356
356/* Reports 19-22: flash upgrade of the C8051F321 */ 357/* Reports 19-22: flash upgrade of the C8051F321 */
358#define WRITE_REPORT_SIZE 4
357#define WRITE_REPORT 19 359#define WRITE_REPORT 19
360#define FLASH_REPORT_SIZE 64
358#define FLASH_REPORT 20 361#define FLASH_REPORT 20
362#define CRC_REPORT_SIZE 3
359#define CRC_REPORT 21 363#define CRC_REPORT 21
364#define RESPONSE_REPORT_SIZE 2
360#define RESPONSE_REPORT 22 365#define RESPONSE_REPORT 22
361 366
362/* Report 23: currently unused, but can accept 60 byte reports on the HID */ 367/* Report 23: currently unused, but can accept 60 byte reports on the HID */
@@ -429,12 +434,6 @@ MODULE_PARM_DESC(rds_poll_time, "RDS poll time (ms): *40*");
429#define COMMAND_FAILED 0x02 434#define COMMAND_FAILED 0x02
430#define COMMAND_PENDING 0x03 435#define COMMAND_PENDING 0x03
431 436
432/* buffer sizes */
433#define COMMAND_BUFFER_SIZE 4
434#define RESPONSE_BUFFER_SIZE 2
435#define FLASH_BUFFER_SIZE 64
436#define CRC_BUFFER_SIZE 3
437
438 437
439 438
440/************************************************************************** 439/**************************************************************************
@@ -466,6 +465,10 @@ struct si470x_device {
466 unsigned int buf_size; 465 unsigned int buf_size;
467 unsigned int rd_index; 466 unsigned int rd_index;
468 unsigned int wr_index; 467 unsigned int wr_index;
468
469 /* scratch page */
470 unsigned char software_version;
471 unsigned char hardware_version;
469}; 472};
470 473
471 474
@@ -834,30 +837,6 @@ static int si470x_rds_on(struct si470x_device *radio)
834 837
835 838
836/************************************************************************** 839/**************************************************************************
837 * General Driver Functions - LED_REPORT
838 **************************************************************************/
839
840/*
841 * si470x_set_led_state - sets the led state
842 */
843static int si470x_set_led_state(struct si470x_device *radio,
844 unsigned char led_state)
845{
846 unsigned char buf[LED_REPORT_SIZE];
847 int retval;
848
849 buf[0] = LED_REPORT;
850 buf[1] = LED_COMMAND;
851 buf[2] = led_state;
852
853 retval = si470x_set_report(radio, (void *) &buf, sizeof(buf));
854
855 return (retval < 0) ? -EINVAL : 0;
856}
857
858
859
860/**************************************************************************
861 * General Driver Functions - ENTIRE_REPORT 840 * General Driver Functions - ENTIRE_REPORT
862 **************************************************************************/ 841 **************************************************************************/
863 842
@@ -922,6 +901,59 @@ static int si470x_get_rds_registers(struct si470x_device *radio)
922 901
923 902
924/************************************************************************** 903/**************************************************************************
904 * General Driver Functions - LED_REPORT
905 **************************************************************************/
906
907/*
908 * si470x_set_led_state - sets the led state
909 */
910static int si470x_set_led_state(struct si470x_device *radio,
911 unsigned char led_state)
912{
913 unsigned char buf[LED_REPORT_SIZE];
914 int retval;
915
916 buf[0] = LED_REPORT;
917 buf[1] = LED_COMMAND;
918 buf[2] = led_state;
919
920 retval = si470x_set_report(radio, (void *) &buf, sizeof(buf));
921
922 return (retval < 0) ? -EINVAL : 0;
923}
924
925
926
927/**************************************************************************
928 * General Driver Functions - SCRATCH_REPORT
929 **************************************************************************/
930
931/*
932 * si470x_get_scratch_versions - gets the scratch page and version infos
933 */
934static int si470x_get_scratch_page_versions(struct si470x_device *radio)
935{
936 unsigned char buf[SCRATCH_REPORT_SIZE];
937 int retval;
938
939 buf[0] = SCRATCH_REPORT;
940
941 retval = si470x_get_report(radio, (void *) &buf, sizeof(buf));
942
943 if (retval < 0)
944 printk(KERN_WARNING DRIVER_NAME ": si470x_get_scratch: "
945 "si470x_get_report returned %d\n", retval);
946 else {
947 radio->software_version = buf[1];
948 radio->hardware_version = buf[2];
949 }
950
951 return (retval < 0) ? -EINVAL : 0;
952}
953
954
955
956/**************************************************************************
925 * RDS Driver Functions 957 * RDS Driver Functions
926 **************************************************************************/ 958 **************************************************************************/
927 959
@@ -1651,7 +1683,7 @@ static int si470x_usb_driver_probe(struct usb_interface *intf,
1651 sizeof(si470x_viddev_template)); 1683 sizeof(si470x_viddev_template));
1652 video_set_drvdata(radio->videodev, radio); 1684 video_set_drvdata(radio->videodev, radio);
1653 1685
1654 /* show some infos about the specific device */ 1686 /* show some infos about the specific si470x device */
1655 if (si470x_get_all_registers(radio) < 0) { 1687 if (si470x_get_all_registers(radio) < 0) {
1656 retval = -EIO; 1688 retval = -EIO;
1657 goto err_all; 1689 goto err_all;
@@ -1659,7 +1691,16 @@ static int si470x_usb_driver_probe(struct usb_interface *intf,
1659 printk(KERN_INFO DRIVER_NAME ": DeviceID=0x%4.4hx ChipID=0x%4.4hx\n", 1691 printk(KERN_INFO DRIVER_NAME ": DeviceID=0x%4.4hx ChipID=0x%4.4hx\n",
1660 radio->registers[DEVICEID], radio->registers[CHIPID]); 1692 radio->registers[DEVICEID], radio->registers[CHIPID]);
1661 1693
1662 /* check if firmware is current */ 1694 /* get software and hardware versions */
1695 if (si470x_get_scratch_page_versions(radio) < 0) {
1696 retval = -EIO;
1697 goto err_all;
1698 }
1699 printk(KERN_INFO DRIVER_NAME
1700 ": software version %d, hardware version %d\n",
1701 radio->software_version, radio->hardware_version);
1702
1703 /* check if device and firmware is current */
1663 if ((radio->registers[CHIPID] & CHIPID_FIRMWARE) 1704 if ((radio->registers[CHIPID] & CHIPID_FIRMWARE)
1664 < RADIO_SW_VERSION_CURRENT) { 1705 < RADIO_SW_VERSION_CURRENT) {
1665 printk(KERN_WARNING DRIVER_NAME 1706 printk(KERN_WARNING DRIVER_NAME