diff options
Diffstat (limited to 'drivers/media/radio/radio-si470x.c')
-rw-r--r-- | drivers/media/radio/radio-si470x.c | 109 |
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 | */ | ||
843 | static 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 | */ | ||
910 | static 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 | */ | ||
934 | static 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 |