aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTobias Lorenz <tobias.lorenz@gmx.net>2008-01-27 12:54:07 -0500
committerMauro Carvalho Chehab <mchehab@infradead.org>2008-02-18 09:14:59 -0500
commit0e3301ec23000ffbbe28771eb79628856a9a2f84 (patch)
treec6d2ab5c24d0a13d4d78b317a60fe4ad1166b218
parent2de3a5a5c52ae1550be537829bb487131430d74b (diff)
V4L/DVB (7091): radio-si470x improvements and seldom problem fixed in tuning functions
I updated the radio-si470x driver another time. Here are the commented history entries: - number of seek_retries changed to tune_timeout The last versions checked for the end of frequency tuning by polling a si470x register. Therefore polling depended on the usb utilization. This was changed to have a constant timeout now. - fixed problem with incomplete tune operations by own buffers The last version used a shared buffer to assembly the USB HID reports. It sometimes happened, that multiple functions were modifing this buffer simultanuously. When sending such reports, the hardware returned USB stalls (-EPIPE). Now buffers of the correct size (smaller than before) are allocated as local variables. - optimization of variables The size of some variables has been reduced to allow the compiler to generate more optimized code. - improved error logging At some important location, error checking was improved. Especially the usb transfers to access si470x registers and the tuning functions were modified. Signed-off-by: Tobias Lorenz <tobias.lorenz@gmx.net> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
-rw-r--r--drivers/media/radio/radio-si470x.c223
1 files changed, 143 insertions, 80 deletions
diff --git a/drivers/media/radio/radio-si470x.c b/drivers/media/radio/radio-si470x.c
index 8e4bd4769048..a2975c8b0095 100644
--- a/drivers/media/radio/radio-si470x.c
+++ b/drivers/media/radio/radio-si470x.c
@@ -62,6 +62,12 @@
62 * - code cleaned of unnecessary rds_commands 62 * - code cleaned of unnecessary rds_commands
63 * - USB Vendor/Product ID for ADS/Tech FM Radio Receiver verified 63 * - USB Vendor/Product ID for ADS/Tech FM Radio Receiver verified
64 * (thanks to Guillaume RAMOUSSE) 64 * (thanks to Guillaume RAMOUSSE)
65 * 2008-01-27 Tobias Lorenz <tobias.lorenz@gmx.net>
66 * Version 1.0.5
67 * - number of seek_retries changed to tune_timeout
68 * - fixed problem with incomplete tune operations by own buffers
69 * - optimization of variables
70 * - improved error logging
65 * 71 *
66 * ToDo: 72 * ToDo:
67 * - add seeking support 73 * - add seeking support
@@ -74,9 +80,10 @@
74/* driver definitions */ 80/* driver definitions */
75#define DRIVER_AUTHOR "Tobias Lorenz <tobias.lorenz@gmx.net>" 81#define DRIVER_AUTHOR "Tobias Lorenz <tobias.lorenz@gmx.net>"
76#define DRIVER_NAME "radio-si470x" 82#define DRIVER_NAME "radio-si470x"
77#define DRIVER_VERSION KERNEL_VERSION(1, 0, 4) 83#define DRIVER_KERNEL_VERSION KERNEL_VERSION(1, 0, 5)
78#define DRIVER_CARD "Silicon Labs Si470x FM Radio Receiver" 84#define DRIVER_CARD "Silicon Labs Si470x FM Radio Receiver"
79#define DRIVER_DESC "USB radio driver for Si470x FM Radio Receivers" 85#define DRIVER_DESC "USB radio driver for Si470x FM Radio Receivers"
86#define DRIVER_VERSION "1.0.5"
80 87
81 88
82/* kernel includes */ 89/* kernel includes */
@@ -119,56 +126,56 @@ MODULE_PARM_DESC(radio_nr, "Radio Nr");
119/* 0: 200 kHz (USA, Australia) */ 126/* 0: 200 kHz (USA, Australia) */
120/* 1: 100 kHz (Europe, Japan) */ 127/* 1: 100 kHz (Europe, Japan) */
121/* 2: 50 kHz */ 128/* 2: 50 kHz */
122static int space = 2; 129static unsigned short space = 2;
123module_param(space, int, 0); 130module_param(space, ushort, 0);
124MODULE_PARM_DESC(radio_nr, "Spacing: 0=200kHz 1=100kHz *2=50kHz*"); 131MODULE_PARM_DESC(radio_nr, "Spacing: 0=200kHz 1=100kHz *2=50kHz*");
125 132
126/* Bottom of Band (MHz) */ 133/* Bottom of Band (MHz) */
127/* 0: 87.5 - 108 MHz (USA, Europe)*/ 134/* 0: 87.5 - 108 MHz (USA, Europe)*/
128/* 1: 76 - 108 MHz (Japan wide band) */ 135/* 1: 76 - 108 MHz (Japan wide band) */
129/* 2: 76 - 90 MHz (Japan) */ 136/* 2: 76 - 90 MHz (Japan) */
130static int band = 1; 137static unsigned short band = 1;
131module_param(band, int, 0); 138module_param(band, ushort, 0);
132MODULE_PARM_DESC(radio_nr, "Band: 0=87.5..108MHz *1=76..108MHz* 2=76..90MHz"); 139MODULE_PARM_DESC(radio_nr, "Band: 0=87.5..108MHz *1=76..108MHz* 2=76..90MHz");
133 140
134/* De-emphasis */ 141/* De-emphasis */
135/* 0: 75 us (USA) */ 142/* 0: 75 us (USA) */
136/* 1: 50 us (Europe, Australia, Japan) */ 143/* 1: 50 us (Europe, Australia, Japan) */
137static int de = 1; 144static unsigned short de = 1;
138module_param(de, int, 0); 145module_param(de, ushort, 0);
139MODULE_PARM_DESC(radio_nr, "De-emphasis: 0=75us *1=50us*"); 146MODULE_PARM_DESC(radio_nr, "De-emphasis: 0=75us *1=50us*");
140 147
141/* USB timeout */ 148/* USB timeout */
142static int usb_timeout = 500; 149static unsigned int usb_timeout = 500;
143module_param(usb_timeout, int, 0); 150module_param(usb_timeout, uint, 0);
144MODULE_PARM_DESC(usb_timeout, "USB timeout (ms): *500*"); 151MODULE_PARM_DESC(usb_timeout, "USB timeout (ms): *500*");
145 152
146/* Seek retries */ 153/* Tune timeout */
147static int seek_retries = 100; 154static unsigned int tune_timeout = 3000;
148module_param(seek_retries, int, 0); 155module_param(tune_timeout, uint, 0);
149MODULE_PARM_DESC(seek_retries, "Seek retries: *100*"); 156MODULE_PARM_DESC(tune_timeout, "Tune timeout: *3000*");
150 157
151/* RDS buffer blocks */ 158/* RDS buffer blocks */
152static int rds_buf = 100; 159static unsigned int rds_buf = 100;
153module_param(rds_buf, int, 0); 160module_param(rds_buf, uint, 0);
154MODULE_PARM_DESC(rds_buf, "RDS buffer entries: *100*"); 161MODULE_PARM_DESC(rds_buf, "RDS buffer entries: *100*");
155 162
156/* RDS maximum block errors */ 163/* RDS maximum block errors */
157static int max_rds_errors = 1; 164static unsigned short max_rds_errors = 1;
158/* 0 means 0 errors requiring correction */ 165/* 0 means 0 errors requiring correction */
159/* 1 means 1-2 errors requiring correction (used by original USBRadio.exe) */ 166/* 1 means 1-2 errors requiring correction (used by original USBRadio.exe) */
160/* 2 means 3-5 errors requiring correction */ 167/* 2 means 3-5 errors requiring correction */
161/* 3 means 6+ errors or errors in checkword, correction not possible */ 168/* 3 means 6+ errors or errors in checkword, correction not possible */
162module_param(max_rds_errors, int, 0); 169module_param(max_rds_errors, ushort, 0);
163MODULE_PARM_DESC(max_rds_errors, "RDS maximum block errors: *1*"); 170MODULE_PARM_DESC(max_rds_errors, "RDS maximum block errors: *1*");
164 171
165/* RDS poll frequency */ 172/* RDS poll frequency */
166static int rds_poll_time = 40; 173static unsigned int rds_poll_time = 40;
167/* 40 is used by the original USBRadio.exe */ 174/* 40 is used by the original USBRadio.exe */
168/* 50 is used by radio-cadet */ 175/* 50 is used by radio-cadet */
169/* 75 should be okay */ 176/* 75 should be okay */
170/* 80 is the usual RDS receive interval */ 177/* 80 is the usual RDS receive interval */
171module_param(rds_poll_time, int, 0); 178module_param(rds_poll_time, uint, 0);
172MODULE_PARM_DESC(rds_poll_time, "RDS poll time (ms): *40*"); 179MODULE_PARM_DESC(rds_poll_time, "RDS poll time (ms): *40*");
173 180
174 181
@@ -395,11 +402,8 @@ struct si470x_device {
395 struct usb_device *usbdev; 402 struct usb_device *usbdev;
396 struct video_device *videodev; 403 struct video_device *videodev;
397 404
398 /* are these really necessary ? */ 405 /* driver management */
399 int users; 406 unsigned int users;
400
401 /* report buffer (maximum 64 bytes) */
402 unsigned char buf[64];
403 407
404 /* Silabs internal registers (0..15) */ 408 /* Silabs internal registers (0..15) */
405 unsigned short registers[RADIO_REGISTER_NUM]; 409 unsigned short registers[RADIO_REGISTER_NUM];
@@ -434,28 +438,46 @@ struct si470x_device {
434/* 438/*
435 * si470x_get_report - receive a HID report 439 * si470x_get_report - receive a HID report
436 */ 440 */
437static int si470x_get_report(struct si470x_device *radio, int size) 441static int si470x_get_report(struct si470x_device *radio, void *buf, int size)
438{ 442{
439 return usb_control_msg(radio->usbdev, 443 unsigned char *report = (unsigned char *) buf;
444 int retval;
445
446 retval = usb_control_msg(radio->usbdev,
440 usb_rcvctrlpipe(radio->usbdev, 0), 447 usb_rcvctrlpipe(radio->usbdev, 0),
441 HID_REQ_GET_REPORT, 448 HID_REQ_GET_REPORT,
442 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, 449 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
443 radio->buf[0], 2, 450 report[0], 2,
444 radio->buf, size, usb_timeout); 451 buf, size, usb_timeout);
452 if (retval < 0)
453 printk(KERN_WARNING DRIVER_NAME
454 ": si470x_get_report: usb_control_msg returned %d\n",
455 retval);
456
457 return retval;
445} 458}
446 459
447 460
448/* 461/*
449 * si470x_set_report - send a HID report 462 * si470x_set_report - send a HID report
450 */ 463 */
451static int si470x_set_report(struct si470x_device *radio, int size) 464static int si470x_set_report(struct si470x_device *radio, void *buf, int size)
452{ 465{
453 return usb_control_msg(radio->usbdev, 466 unsigned char *report = (unsigned char *) buf;
467 int retval;
468
469 retval = usb_control_msg(radio->usbdev,
454 usb_sndctrlpipe(radio->usbdev, 0), 470 usb_sndctrlpipe(radio->usbdev, 0),
455 HID_REQ_SET_REPORT, 471 HID_REQ_SET_REPORT,
456 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT, 472 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
457 radio->buf[0], 2, 473 report[0], 2,
458 radio->buf, size, usb_timeout); 474 buf, size, usb_timeout);
475 if (retval < 0)
476 printk(KERN_WARNING DRIVER_NAME
477 ": si470x_set_report: usb_control_msg returned %d\n",
478 retval);
479
480 return retval;
459} 481}
460 482
461 483
@@ -464,13 +486,15 @@ static int si470x_set_report(struct si470x_device *radio, int size)
464 */ 486 */
465static int si470x_get_register(struct si470x_device *radio, int regnr) 487static int si470x_get_register(struct si470x_device *radio, int regnr)
466{ 488{
489 unsigned char buf[REGISTER_REPORT_SIZE];
467 int retval; 490 int retval;
468 491
469 radio->buf[0] = REGISTER_REPORT(regnr); 492 buf[0] = REGISTER_REPORT(regnr);
493
494 retval = si470x_get_report(radio, (void *) &buf, sizeof(buf));
470 495
471 retval = si470x_get_report(radio, REGISTER_REPORT_SIZE);
472 if (retval >= 0) 496 if (retval >= 0)
473 radio->registers[regnr] = (radio->buf[1] << 8) | radio->buf[2]; 497 radio->registers[regnr] = (buf[1] << 8) | buf[2];
474 498
475 return (retval < 0) ? -EINVAL : 0; 499 return (retval < 0) ? -EINVAL : 0;
476} 500}
@@ -481,13 +505,14 @@ static int si470x_get_register(struct si470x_device *radio, int regnr)
481 */ 505 */
482static int si470x_set_register(struct si470x_device *radio, int regnr) 506static int si470x_set_register(struct si470x_device *radio, int regnr)
483{ 507{
508 unsigned char buf[REGISTER_REPORT_SIZE];
484 int retval; 509 int retval;
485 510
486 radio->buf[0] = REGISTER_REPORT(regnr); 511 buf[0] = REGISTER_REPORT(regnr);
487 radio->buf[1] = (radio->registers[regnr] & 0xff00) >> 8; 512 buf[1] = (radio->registers[regnr] & 0xff00) >> 8;
488 radio->buf[2] = (radio->registers[regnr] & 0x00ff); 513 buf[2] = (radio->registers[regnr] & 0x00ff);
489 514
490 retval = si470x_set_report(radio, REGISTER_REPORT_SIZE); 515 retval = si470x_set_report(radio, (void *) &buf, sizeof(buf));
491 516
492 return (retval < 0) ? -EINVAL : 0; 517 return (retval < 0) ? -EINVAL : 0;
493} 518}
@@ -498,18 +523,19 @@ static int si470x_set_register(struct si470x_device *radio, int regnr)
498 */ 523 */
499static int si470x_get_all_registers(struct si470x_device *radio) 524static int si470x_get_all_registers(struct si470x_device *radio)
500{ 525{
526 unsigned char buf[ENTIRE_REPORT_SIZE];
501 int retval; 527 int retval;
502 int regnr; 528 unsigned char regnr;
503 529
504 radio->buf[0] = ENTIRE_REPORT; 530 buf[0] = ENTIRE_REPORT;
505 531
506 retval = si470x_get_report(radio, ENTIRE_REPORT_SIZE); 532 retval = si470x_get_report(radio, (void *) &buf, sizeof(buf));
507 533
508 if (retval >= 0) 534 if (retval >= 0)
509 for (regnr = 0; regnr < RADIO_REGISTER_NUM; regnr++) 535 for (regnr = 0; regnr < RADIO_REGISTER_NUM; regnr++)
510 radio->registers[regnr] = 536 radio->registers[regnr] =
511 (radio->buf[regnr * RADIO_REGISTER_SIZE + 1] << 8) | 537 (buf[regnr * RADIO_REGISTER_SIZE + 1] << 8) |
512 radio->buf[regnr * RADIO_REGISTER_SIZE + 2]; 538 buf[regnr * RADIO_REGISTER_SIZE + 2];
513 539
514 return (retval < 0) ? -EINVAL : 0; 540 return (retval < 0) ? -EINVAL : 0;
515} 541}
@@ -520,21 +546,28 @@ static int si470x_get_all_registers(struct si470x_device *radio)
520 */ 546 */
521static int si470x_get_rds_registers(struct si470x_device *radio) 547static int si470x_get_rds_registers(struct si470x_device *radio)
522{ 548{
549 unsigned char buf[RDS_REPORT_SIZE];
523 int retval; 550 int retval;
524 int regnr;
525 int size; 551 int size;
552 unsigned char regnr;
526 553
527 radio->buf[0] = RDS_REPORT; 554 buf[0] = RDS_REPORT;
528 555
529 retval = usb_interrupt_msg(radio->usbdev, 556 retval = usb_interrupt_msg(radio->usbdev,
530 usb_rcvctrlpipe(radio->usbdev, 1), 557 usb_rcvintpipe(radio->usbdev, 1),
531 radio->buf, RDS_REPORT_SIZE, &size, usb_timeout); 558 (void *) &buf, sizeof(buf), &size, usb_timeout);
559 if (size != sizeof(buf))
560 printk(KERN_WARNING DRIVER_NAME ": si470x_get_rds_register: "
561 "return size differs: %d != %d\n", size, sizeof(buf));
562 if (retval < 0)
563 printk(KERN_WARNING DRIVER_NAME ": si470x_get_rds_registers: "
564 "usb_interrupt_msg returned %d\n", retval);
532 565
533 if (retval >= 0) 566 if (retval >= 0)
534 for (regnr = 0; regnr < RDS_REGISTER_NUM; regnr++) 567 for (regnr = 0; regnr < RDS_REGISTER_NUM; regnr++)
535 radio->registers[STATUSRSSI + regnr] = 568 radio->registers[STATUSRSSI + regnr] =
536 (radio->buf[regnr * RADIO_REGISTER_SIZE + 1] << 8) | 569 (buf[regnr * RADIO_REGISTER_SIZE + 1] << 8) |
537 radio->buf[regnr * RADIO_REGISTER_SIZE + 2]; 570 buf[regnr * RADIO_REGISTER_SIZE + 2];
538 571
539 return (retval < 0) ? -EINVAL : 0; 572 return (retval < 0) ? -EINVAL : 0;
540} 573}
@@ -543,9 +576,11 @@ static int si470x_get_rds_registers(struct si470x_device *radio)
543/* 576/*
544 * si470x_set_chan - set the channel 577 * si470x_set_chan - set the channel
545 */ 578 */
546static int si470x_set_chan(struct si470x_device *radio, int chan) 579static int si470x_set_chan(struct si470x_device *radio, unsigned short chan)
547{ 580{
548 int retval, i; 581 int retval;
582 unsigned long timeout;
583 bool timed_out = 0;
549 584
550 /* start tuning */ 585 /* start tuning */
551 radio->registers[CHANNEL] &= ~CHANNEL_CHAN; 586 radio->registers[CHANNEL] &= ~CHANNEL_CHAN;
@@ -555,16 +590,17 @@ static int si470x_set_chan(struct si470x_device *radio, int chan)
555 return retval; 590 return retval;
556 591
557 /* wait till seek operation has completed */ 592 /* wait till seek operation has completed */
558 i = 0; 593 timeout = jiffies + msecs_to_jiffies(tune_timeout);
559 do { 594 do {
560 retval = si470x_get_register(radio, STATUSRSSI); 595 retval = si470x_get_register(radio, STATUSRSSI);
561 if (retval < 0) 596 if (retval < 0)
562 return retval; 597 return retval;
563 } while ((radio->registers[STATUSRSSI] & STATUSRSSI_STC) && 598 timed_out = time_after(jiffies, timeout);
564 (++i < seek_retries)); 599 } while (((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0) &&
565 if (i >= seek_retries) 600 (!timed_out));
601 if (timed_out)
566 printk(KERN_WARNING DRIVER_NAME 602 printk(KERN_WARNING DRIVER_NAME
567 ": seek does not finish after %d tries\n", i); 603 ": seek does not finish after %d ms\n", tune_timeout);
568 604
569 /* stop tuning */ 605 /* stop tuning */
570 radio->registers[CHANNEL] &= ~CHANNEL_TUNE; 606 radio->registers[CHANNEL] &= ~CHANNEL_TUNE;
@@ -575,9 +611,10 @@ static int si470x_set_chan(struct si470x_device *radio, int chan)
575/* 611/*
576 * si470x_get_freq - get the frequency 612 * si470x_get_freq - get the frequency
577 */ 613 */
578static int si470x_get_freq(struct si470x_device *radio) 614static unsigned int si470x_get_freq(struct si470x_device *radio)
579{ 615{
580 int spacing, band_bottom, chan, freq; 616 unsigned int spacing, band_bottom, freq;
617 unsigned short chan;
581 int retval; 618 int retval;
582 619
583 /* Spacing (kHz) */ 620 /* Spacing (kHz) */
@@ -616,9 +653,10 @@ static int si470x_get_freq(struct si470x_device *radio)
616/* 653/*
617 * si470x_set_freq - set the frequency 654 * si470x_set_freq - set the frequency
618 */ 655 */
619static int si470x_set_freq(struct si470x_device *radio, int freq) 656static int si470x_set_freq(struct si470x_device *radio, unsigned int freq)
620{ 657{
621 int spacing, band_bottom, chan; 658 unsigned int spacing, band_bottom;
659 unsigned short chan;
622 660
623 /* Spacing (kHz) */ 661 /* Spacing (kHz) */
624 switch (space) { 662 switch (space) {
@@ -725,12 +763,6 @@ static int si470x_rds_on(struct si470x_device *radio)
725 */ 763 */
726static void si470x_rds(struct si470x_device *radio) 764static void si470x_rds(struct si470x_device *radio)
727{ 765{
728 unsigned char tmpbuf[3];
729 unsigned char blocknum;
730 unsigned char bler; /* rds block errors */
731 unsigned short rds;
732 unsigned int i;
733
734 /* get rds blocks */ 766 /* get rds blocks */
735 if (si470x_get_rds_registers(radio) < 0) 767 if (si470x_get_rds_registers(radio) < 0)
736 return; 768 return;
@@ -745,6 +777,12 @@ static void si470x_rds(struct si470x_device *radio)
745 777
746 /* copy four RDS blocks to internal buffer */ 778 /* copy four RDS blocks to internal buffer */
747 if (spin_trylock(&radio->lock)) { 779 if (spin_trylock(&radio->lock)) {
780 unsigned char blocknum;
781 unsigned short bler; /* rds block errors */
782 unsigned short rds;
783 unsigned char tmpbuf[3];
784 unsigned char i;
785
748 /* process each rds block */ 786 /* process each rds block */
749 for (blocknum = 0; blocknum < 4; blocknum++) { 787 for (blocknum = 0; blocknum < 4; blocknum++) {
750 switch (blocknum) { 788 switch (blocknum) {
@@ -847,7 +885,6 @@ static ssize_t si470x_fops_read(struct file *file, char __user *buf,
847{ 885{
848 struct si470x_device *radio = video_get_drvdata(video_devdata(file)); 886 struct si470x_device *radio = video_get_drvdata(video_devdata(file));
849 int retval = 0; 887 int retval = 0;
850 unsigned int block_count = 0;
851 888
852 /* switch on rds reception */ 889 /* switch on rds reception */
853 if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0) { 890 if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0) {
@@ -867,6 +904,7 @@ static ssize_t si470x_fops_read(struct file *file, char __user *buf,
867 904
868 /* copy RDS block out of internal buffer and to user buffer */ 905 /* copy RDS block out of internal buffer and to user buffer */
869 if (spin_trylock(&radio->lock)) { 906 if (spin_trylock(&radio->lock)) {
907 unsigned int block_count = 0;
870 while (block_count < count) { 908 while (block_count < count) {
871 if (radio->rd_index == radio->wr_index) 909 if (radio->rd_index == radio->wr_index)
872 break; 910 break;
@@ -1030,7 +1068,7 @@ static int si470x_vidioc_querycap(struct file *file, void *priv,
1030 strlcpy(capability->driver, DRIVER_NAME, sizeof(capability->driver)); 1068 strlcpy(capability->driver, DRIVER_NAME, sizeof(capability->driver));
1031 strlcpy(capability->card, DRIVER_CARD, sizeof(capability->card)); 1069 strlcpy(capability->card, DRIVER_CARD, sizeof(capability->card));
1032 sprintf(capability->bus_info, "USB"); 1070 sprintf(capability->bus_info, "USB");
1033 capability->version = DRIVER_VERSION; 1071 capability->version = DRIVER_KERNEL_VERSION;
1034 capability->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO; 1072 capability->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
1035 1073
1036 return 0; 1074 return 0;
@@ -1067,16 +1105,21 @@ static int si470x_vidioc_s_input(struct file *filp, void *priv, unsigned int i)
1067static int si470x_vidioc_queryctrl(struct file *file, void *priv, 1105static int si470x_vidioc_queryctrl(struct file *file, void *priv,
1068 struct v4l2_queryctrl *qc) 1106 struct v4l2_queryctrl *qc)
1069{ 1107{
1070 int i; 1108 unsigned char i;
1109 int retval = -EINVAL;
1071 1110
1072 for (i = 0; i < ARRAY_SIZE(si470x_v4l2_queryctrl); i++) { 1111 for (i = 0; i < ARRAY_SIZE(si470x_v4l2_queryctrl); i++) {
1073 if (qc->id && qc->id == si470x_v4l2_queryctrl[i].id) { 1112 if (qc->id && qc->id == si470x_v4l2_queryctrl[i].id) {
1074 memcpy(qc, &(si470x_v4l2_queryctrl[i]), sizeof(*qc)); 1113 memcpy(qc, &(si470x_v4l2_queryctrl[i]), sizeof(*qc));
1075 return 0; 1114 retval = 0;
1115 break;
1076 } 1116 }
1077 } 1117 }
1118 if (retval < 0)
1119 printk(KERN_WARNING DRIVER_NAME
1120 ": query control failed with %d\n", retval);
1078 1121
1079 return -EINVAL; 1122 return retval;
1080} 1123}
1081 1124
1082 1125
@@ -1110,21 +1153,29 @@ static int si470x_vidioc_s_ctrl(struct file *file, void *priv,
1110 struct v4l2_control *ctrl) 1153 struct v4l2_control *ctrl)
1111{ 1154{
1112 struct si470x_device *radio = video_get_drvdata(video_devdata(file)); 1155 struct si470x_device *radio = video_get_drvdata(video_devdata(file));
1156 int retval;
1113 1157
1114 switch (ctrl->id) { 1158 switch (ctrl->id) {
1115 case V4L2_CID_AUDIO_VOLUME: 1159 case V4L2_CID_AUDIO_VOLUME:
1116 radio->registers[SYSCONFIG2] &= ~SYSCONFIG2_VOLUME; 1160 radio->registers[SYSCONFIG2] &= ~SYSCONFIG2_VOLUME;
1117 radio->registers[SYSCONFIG2] |= ctrl->value; 1161 radio->registers[SYSCONFIG2] |= ctrl->value;
1118 return si470x_set_register(radio, SYSCONFIG2); 1162 retval = si470x_set_register(radio, SYSCONFIG2);
1163 break;
1119 case V4L2_CID_AUDIO_MUTE: 1164 case V4L2_CID_AUDIO_MUTE:
1120 if (ctrl->value == 1) 1165 if (ctrl->value == 1)
1121 radio->registers[POWERCFG] &= ~POWERCFG_DMUTE; 1166 radio->registers[POWERCFG] &= ~POWERCFG_DMUTE;
1122 else 1167 else
1123 radio->registers[POWERCFG] |= POWERCFG_DMUTE; 1168 radio->registers[POWERCFG] |= POWERCFG_DMUTE;
1124 return si470x_set_register(radio, POWERCFG); 1169 retval = si470x_set_register(radio, POWERCFG);
1170 break;
1171 default:
1172 retval = -EINVAL;
1125 } 1173 }
1174 if (retval < 0)
1175 printk(KERN_WARNING DRIVER_NAME
1176 ": set control failed with %d\n", retval);
1126 1177
1127 return -EINVAL; 1178 return retval;
1128} 1179}
1129 1180
1130 1181
@@ -1163,8 +1214,8 @@ static int si470x_vidioc_s_audio(struct file *file, void *priv,
1163static int si470x_vidioc_g_tuner(struct file *file, void *priv, 1214static int si470x_vidioc_g_tuner(struct file *file, void *priv,
1164 struct v4l2_tuner *tuner) 1215 struct v4l2_tuner *tuner)
1165{ 1216{
1166 int retval;
1167 struct si470x_device *radio = video_get_drvdata(video_devdata(file)); 1217 struct si470x_device *radio = video_get_drvdata(video_devdata(file));
1218 int retval;
1168 1219
1169 if (tuner->index > 0) 1220 if (tuner->index > 0)
1170 return -EINVAL; 1221 return -EINVAL;
@@ -1220,6 +1271,7 @@ static int si470x_vidioc_s_tuner(struct file *file, void *priv,
1220 struct v4l2_tuner *tuner) 1271 struct v4l2_tuner *tuner)
1221{ 1272{
1222 struct si470x_device *radio = video_get_drvdata(video_devdata(file)); 1273 struct si470x_device *radio = video_get_drvdata(video_devdata(file));
1274 int retval;
1223 1275
1224 if (tuner->index > 0) 1276 if (tuner->index > 0)
1225 return -EINVAL; 1277 return -EINVAL;
@@ -1229,7 +1281,12 @@ static int si470x_vidioc_s_tuner(struct file *file, void *priv,
1229 else 1281 else
1230 radio->registers[POWERCFG] &= ~POWERCFG_MONO; /* try stereo */ 1282 radio->registers[POWERCFG] &= ~POWERCFG_MONO; /* try stereo */
1231 1283
1232 return si470x_set_register(radio, POWERCFG); 1284 retval = si470x_set_register(radio, POWERCFG);
1285 if (retval < 0)
1286 printk(KERN_WARNING DRIVER_NAME
1287 ": set tuner failed with %d\n", retval);
1288
1289 return retval;
1233} 1290}
1234 1291
1235 1292
@@ -1255,11 +1312,17 @@ static int si470x_vidioc_s_frequency(struct file *file, void *priv,
1255 struct v4l2_frequency *freq) 1312 struct v4l2_frequency *freq)
1256{ 1313{
1257 struct si470x_device *radio = video_get_drvdata(video_devdata(file)); 1314 struct si470x_device *radio = video_get_drvdata(video_devdata(file));
1315 int retval;
1258 1316
1259 if (freq->type != V4L2_TUNER_RADIO) 1317 if (freq->type != V4L2_TUNER_RADIO)
1260 return -EINVAL; 1318 return -EINVAL;
1261 1319
1262 return si470x_set_freq(radio, freq->frequency); 1320 retval = si470x_set_freq(radio, freq->frequency);
1321 if (retval < 0)
1322 printk(KERN_WARNING DRIVER_NAME
1323 ": set frequency failed with %d\n", retval);
1324
1325 return 0;
1263} 1326}
1264 1327
1265 1328
@@ -1409,7 +1472,7 @@ static struct usb_driver si470x_usb_driver = {
1409 */ 1472 */
1410static int __init si470x_module_init(void) 1473static int __init si470x_module_init(void)
1411{ 1474{
1412 printk(KERN_INFO DRIVER_DESC "\n"); 1475 printk(KERN_INFO DRIVER_DESC ", Version " DRIVER_VERSION "\n");
1413 return usb_register(&si470x_usb_driver); 1476 return usb_register(&si470x_usb_driver);
1414} 1477}
1415 1478
@@ -1429,4 +1492,4 @@ module_exit(si470x_module_exit);
1429MODULE_LICENSE("GPL"); 1492MODULE_LICENSE("GPL");
1430MODULE_AUTHOR(DRIVER_AUTHOR); 1493MODULE_AUTHOR(DRIVER_AUTHOR);
1431MODULE_DESCRIPTION(DRIVER_DESC); 1494MODULE_DESCRIPTION(DRIVER_DESC);
1432MODULE_VERSION("1.0.4"); 1495MODULE_VERSION(DRIVER_VERSION);