diff options
Diffstat (limited to 'drivers/media/radio/si470x/radio-si470x-common.c')
-rw-r--r-- | drivers/media/radio/si470x/radio-si470x-common.c | 305 |
1 files changed, 62 insertions, 243 deletions
diff --git a/drivers/media/radio/si470x/radio-si470x-common.c b/drivers/media/radio/si470x/radio-si470x-common.c index 0e740c98786c..969cf494d85b 100644 --- a/drivers/media/radio/si470x/radio-si470x-common.c +++ b/drivers/media/radio/si470x/radio-si470x-common.c | |||
@@ -196,9 +196,9 @@ static int si470x_set_chan(struct si470x_device *radio, unsigned short chan) | |||
196 | } | 196 | } |
197 | 197 | ||
198 | if ((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0) | 198 | if ((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0) |
199 | dev_warn(&radio->videodev->dev, "tune does not complete\n"); | 199 | dev_warn(&radio->videodev.dev, "tune does not complete\n"); |
200 | if (timed_out) | 200 | if (timed_out) |
201 | dev_warn(&radio->videodev->dev, | 201 | dev_warn(&radio->videodev.dev, |
202 | "tune timed out after %u ms\n", tune_timeout); | 202 | "tune timed out after %u ms\n", tune_timeout); |
203 | 203 | ||
204 | stop: | 204 | stop: |
@@ -262,7 +262,7 @@ static int si470x_get_freq(struct si470x_device *radio, unsigned int *freq) | |||
262 | */ | 262 | */ |
263 | int si470x_set_freq(struct si470x_device *radio, unsigned int freq) | 263 | int si470x_set_freq(struct si470x_device *radio, unsigned int freq) |
264 | { | 264 | { |
265 | unsigned int spacing, band_bottom; | 265 | unsigned int spacing, band_bottom, band_top; |
266 | unsigned short chan; | 266 | unsigned short chan; |
267 | 267 | ||
268 | /* Spacing (kHz) */ | 268 | /* Spacing (kHz) */ |
@@ -278,19 +278,26 @@ int si470x_set_freq(struct si470x_device *radio, unsigned int freq) | |||
278 | spacing = 0.050 * FREQ_MUL; break; | 278 | spacing = 0.050 * FREQ_MUL; break; |
279 | }; | 279 | }; |
280 | 280 | ||
281 | /* Bottom of Band (MHz) */ | 281 | /* Bottom/Top of Band (MHz) */ |
282 | switch ((radio->registers[SYSCONFIG2] & SYSCONFIG2_BAND) >> 6) { | 282 | switch ((radio->registers[SYSCONFIG2] & SYSCONFIG2_BAND) >> 6) { |
283 | /* 0: 87.5 - 108 MHz (USA, Europe) */ | 283 | /* 0: 87.5 - 108 MHz (USA, Europe) */ |
284 | case 0: | 284 | case 0: |
285 | band_bottom = 87.5 * FREQ_MUL; break; | 285 | band_bottom = 87.5 * FREQ_MUL; |
286 | band_top = 108 * FREQ_MUL; | ||
287 | break; | ||
286 | /* 1: 76 - 108 MHz (Japan wide band) */ | 288 | /* 1: 76 - 108 MHz (Japan wide band) */ |
287 | default: | 289 | default: |
288 | band_bottom = 76 * FREQ_MUL; break; | 290 | band_bottom = 76 * FREQ_MUL; |
291 | band_top = 108 * FREQ_MUL; | ||
292 | break; | ||
289 | /* 2: 76 - 90 MHz (Japan) */ | 293 | /* 2: 76 - 90 MHz (Japan) */ |
290 | case 2: | 294 | case 2: |
291 | band_bottom = 76 * FREQ_MUL; break; | 295 | band_bottom = 76 * FREQ_MUL; |
296 | band_top = 90 * FREQ_MUL; | ||
297 | break; | ||
292 | }; | 298 | }; |
293 | 299 | ||
300 | freq = clamp(freq, band_bottom, band_top); | ||
294 | /* Chan = [ Freq (Mhz) - Bottom of Band (MHz) ] / Spacing (kHz) */ | 301 | /* Chan = [ Freq (Mhz) - Bottom of Band (MHz) ] / Spacing (kHz) */ |
295 | chan = (freq - band_bottom) / spacing; | 302 | chan = (freq - band_bottom) / spacing; |
296 | 303 | ||
@@ -320,7 +327,7 @@ static int si470x_set_seek(struct si470x_device *radio, | |||
320 | radio->registers[POWERCFG] &= ~POWERCFG_SEEKUP; | 327 | radio->registers[POWERCFG] &= ~POWERCFG_SEEKUP; |
321 | retval = si470x_set_register(radio, POWERCFG); | 328 | retval = si470x_set_register(radio, POWERCFG); |
322 | if (retval < 0) | 329 | if (retval < 0) |
323 | goto done; | 330 | return retval; |
324 | 331 | ||
325 | /* currently I2C driver only uses interrupt way to seek */ | 332 | /* currently I2C driver only uses interrupt way to seek */ |
326 | if (radio->stci_enabled) { | 333 | if (radio->stci_enabled) { |
@@ -344,24 +351,19 @@ static int si470x_set_seek(struct si470x_device *radio, | |||
344 | } | 351 | } |
345 | 352 | ||
346 | if ((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0) | 353 | if ((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0) |
347 | dev_warn(&radio->videodev->dev, "seek does not complete\n"); | 354 | dev_warn(&radio->videodev.dev, "seek does not complete\n"); |
348 | if (radio->registers[STATUSRSSI] & STATUSRSSI_SF) | 355 | if (radio->registers[STATUSRSSI] & STATUSRSSI_SF) |
349 | dev_warn(&radio->videodev->dev, | 356 | dev_warn(&radio->videodev.dev, |
350 | "seek failed / band limit reached\n"); | 357 | "seek failed / band limit reached\n"); |
351 | if (timed_out) | ||
352 | dev_warn(&radio->videodev->dev, | ||
353 | "seek timed out after %u ms\n", seek_timeout); | ||
354 | 358 | ||
355 | stop: | 359 | stop: |
356 | /* stop seeking */ | 360 | /* stop seeking */ |
357 | radio->registers[POWERCFG] &= ~POWERCFG_SEEK; | 361 | radio->registers[POWERCFG] &= ~POWERCFG_SEEK; |
358 | retval = si470x_set_register(radio, POWERCFG); | 362 | retval = si470x_set_register(radio, POWERCFG); |
359 | 363 | ||
360 | done: | ||
361 | /* try again, if timed out */ | 364 | /* try again, if timed out */ |
362 | if ((retval == 0) && timed_out) | 365 | if (retval == 0 && timed_out) |
363 | retval = -EAGAIN; | 366 | return -EAGAIN; |
364 | |||
365 | return retval; | 367 | return retval; |
366 | } | 368 | } |
367 | 369 | ||
@@ -463,7 +465,6 @@ static ssize_t si470x_fops_read(struct file *file, char __user *buf, | |||
463 | unsigned int block_count = 0; | 465 | unsigned int block_count = 0; |
464 | 466 | ||
465 | /* switch on rds reception */ | 467 | /* switch on rds reception */ |
466 | mutex_lock(&radio->lock); | ||
467 | if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0) | 468 | if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0) |
468 | si470x_rds_on(radio); | 469 | si470x_rds_on(radio); |
469 | 470 | ||
@@ -505,7 +506,6 @@ static ssize_t si470x_fops_read(struct file *file, char __user *buf, | |||
505 | } | 506 | } |
506 | 507 | ||
507 | done: | 508 | done: |
508 | mutex_unlock(&radio->lock); | ||
509 | return retval; | 509 | return retval; |
510 | } | 510 | } |
511 | 511 | ||
@@ -517,19 +517,19 @@ static unsigned int si470x_fops_poll(struct file *file, | |||
517 | struct poll_table_struct *pts) | 517 | struct poll_table_struct *pts) |
518 | { | 518 | { |
519 | struct si470x_device *radio = video_drvdata(file); | 519 | struct si470x_device *radio = video_drvdata(file); |
520 | int retval = 0; | 520 | unsigned long req_events = poll_requested_events(pts); |
521 | int retval = v4l2_ctrl_poll(file, pts); | ||
521 | 522 | ||
522 | /* switch on rds reception */ | 523 | if (req_events & (POLLIN | POLLRDNORM)) { |
523 | 524 | /* switch on rds reception */ | |
524 | mutex_lock(&radio->lock); | 525 | if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0) |
525 | if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0) | 526 | si470x_rds_on(radio); |
526 | si470x_rds_on(radio); | ||
527 | mutex_unlock(&radio->lock); | ||
528 | 527 | ||
529 | poll_wait(file, &radio->read_queue, pts); | 528 | poll_wait(file, &radio->read_queue, pts); |
530 | 529 | ||
531 | if (radio->rd_index != radio->wr_index) | 530 | if (radio->rd_index != radio->wr_index) |
532 | retval = POLLIN | POLLRDNORM; | 531 | retval |= POLLIN | POLLRDNORM; |
532 | } | ||
533 | 533 | ||
534 | return retval; | 534 | return retval; |
535 | } | 535 | } |
@@ -553,134 +553,26 @@ static const struct v4l2_file_operations si470x_fops = { | |||
553 | * Video4Linux Interface | 553 | * Video4Linux Interface |
554 | **************************************************************************/ | 554 | **************************************************************************/ |
555 | 555 | ||
556 | /* | ||
557 | * si470x_vidioc_queryctrl - enumerate control items | ||
558 | */ | ||
559 | static int si470x_vidioc_queryctrl(struct file *file, void *priv, | ||
560 | struct v4l2_queryctrl *qc) | ||
561 | { | ||
562 | struct si470x_device *radio = video_drvdata(file); | ||
563 | int retval = -EINVAL; | ||
564 | |||
565 | /* abort if qc->id is below V4L2_CID_BASE */ | ||
566 | if (qc->id < V4L2_CID_BASE) | ||
567 | goto done; | ||
568 | |||
569 | /* search video control */ | ||
570 | switch (qc->id) { | ||
571 | case V4L2_CID_AUDIO_VOLUME: | ||
572 | return v4l2_ctrl_query_fill(qc, 0, 15, 1, 15); | ||
573 | case V4L2_CID_AUDIO_MUTE: | ||
574 | return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1); | ||
575 | } | ||
576 | |||
577 | /* disable unsupported base controls */ | ||
578 | /* to satisfy kradio and such apps */ | ||
579 | if ((retval == -EINVAL) && (qc->id < V4L2_CID_LASTP1)) { | ||
580 | qc->flags = V4L2_CTRL_FLAG_DISABLED; | ||
581 | retval = 0; | ||
582 | } | ||
583 | 556 | ||
584 | done: | 557 | static int si470x_s_ctrl(struct v4l2_ctrl *ctrl) |
585 | if (retval < 0) | ||
586 | dev_warn(&radio->videodev->dev, | ||
587 | "query controls failed with %d\n", retval); | ||
588 | return retval; | ||
589 | } | ||
590 | |||
591 | |||
592 | /* | ||
593 | * si470x_vidioc_g_ctrl - get the value of a control | ||
594 | */ | ||
595 | static int si470x_vidioc_g_ctrl(struct file *file, void *priv, | ||
596 | struct v4l2_control *ctrl) | ||
597 | { | ||
598 | struct si470x_device *radio = video_drvdata(file); | ||
599 | int retval = 0; | ||
600 | |||
601 | mutex_lock(&radio->lock); | ||
602 | /* safety checks */ | ||
603 | retval = si470x_disconnect_check(radio); | ||
604 | if (retval) | ||
605 | goto done; | ||
606 | |||
607 | switch (ctrl->id) { | ||
608 | case V4L2_CID_AUDIO_VOLUME: | ||
609 | ctrl->value = radio->registers[SYSCONFIG2] & | ||
610 | SYSCONFIG2_VOLUME; | ||
611 | break; | ||
612 | case V4L2_CID_AUDIO_MUTE: | ||
613 | ctrl->value = ((radio->registers[POWERCFG] & | ||
614 | POWERCFG_DMUTE) == 0) ? 1 : 0; | ||
615 | break; | ||
616 | default: | ||
617 | retval = -EINVAL; | ||
618 | } | ||
619 | |||
620 | done: | ||
621 | if (retval < 0) | ||
622 | dev_warn(&radio->videodev->dev, | ||
623 | "get control failed with %d\n", retval); | ||
624 | |||
625 | mutex_unlock(&radio->lock); | ||
626 | return retval; | ||
627 | } | ||
628 | |||
629 | |||
630 | /* | ||
631 | * si470x_vidioc_s_ctrl - set the value of a control | ||
632 | */ | ||
633 | static int si470x_vidioc_s_ctrl(struct file *file, void *priv, | ||
634 | struct v4l2_control *ctrl) | ||
635 | { | 558 | { |
636 | struct si470x_device *radio = video_drvdata(file); | 559 | struct si470x_device *radio = |
637 | int retval = 0; | 560 | container_of(ctrl->handler, struct si470x_device, hdl); |
638 | |||
639 | mutex_lock(&radio->lock); | ||
640 | /* safety checks */ | ||
641 | retval = si470x_disconnect_check(radio); | ||
642 | if (retval) | ||
643 | goto done; | ||
644 | 561 | ||
645 | switch (ctrl->id) { | 562 | switch (ctrl->id) { |
646 | case V4L2_CID_AUDIO_VOLUME: | 563 | case V4L2_CID_AUDIO_VOLUME: |
647 | radio->registers[SYSCONFIG2] &= ~SYSCONFIG2_VOLUME; | 564 | radio->registers[SYSCONFIG2] &= ~SYSCONFIG2_VOLUME; |
648 | radio->registers[SYSCONFIG2] |= ctrl->value; | 565 | radio->registers[SYSCONFIG2] |= ctrl->val; |
649 | retval = si470x_set_register(radio, SYSCONFIG2); | 566 | return si470x_set_register(radio, SYSCONFIG2); |
650 | break; | ||
651 | case V4L2_CID_AUDIO_MUTE: | 567 | case V4L2_CID_AUDIO_MUTE: |
652 | if (ctrl->value == 1) | 568 | if (ctrl->val) |
653 | radio->registers[POWERCFG] &= ~POWERCFG_DMUTE; | 569 | radio->registers[POWERCFG] &= ~POWERCFG_DMUTE; |
654 | else | 570 | else |
655 | radio->registers[POWERCFG] |= POWERCFG_DMUTE; | 571 | radio->registers[POWERCFG] |= POWERCFG_DMUTE; |
656 | retval = si470x_set_register(radio, POWERCFG); | 572 | return si470x_set_register(radio, POWERCFG); |
657 | break; | ||
658 | default: | 573 | default: |
659 | retval = -EINVAL; | 574 | return -EINVAL; |
660 | } | 575 | } |
661 | |||
662 | done: | ||
663 | if (retval < 0) | ||
664 | dev_warn(&radio->videodev->dev, | ||
665 | "set control failed with %d\n", retval); | ||
666 | mutex_unlock(&radio->lock); | ||
667 | return retval; | ||
668 | } | ||
669 | |||
670 | |||
671 | /* | ||
672 | * si470x_vidioc_g_audio - get audio attributes | ||
673 | */ | ||
674 | static int si470x_vidioc_g_audio(struct file *file, void *priv, | ||
675 | struct v4l2_audio *audio) | ||
676 | { | ||
677 | /* driver constants */ | ||
678 | audio->index = 0; | ||
679 | strcpy(audio->name, "Radio"); | ||
680 | audio->capability = V4L2_AUDCAP_STEREO; | ||
681 | audio->mode = 0; | ||
682 | |||
683 | return 0; | ||
684 | } | 576 | } |
685 | 577 | ||
686 | 578 | ||
@@ -691,22 +583,14 @@ static int si470x_vidioc_g_tuner(struct file *file, void *priv, | |||
691 | struct v4l2_tuner *tuner) | 583 | struct v4l2_tuner *tuner) |
692 | { | 584 | { |
693 | struct si470x_device *radio = video_drvdata(file); | 585 | struct si470x_device *radio = video_drvdata(file); |
694 | int retval = 0; | 586 | int retval; |
695 | |||
696 | mutex_lock(&radio->lock); | ||
697 | /* safety checks */ | ||
698 | retval = si470x_disconnect_check(radio); | ||
699 | if (retval) | ||
700 | goto done; | ||
701 | 587 | ||
702 | if (tuner->index != 0) { | 588 | if (tuner->index != 0) |
703 | retval = -EINVAL; | 589 | return -EINVAL; |
704 | goto done; | ||
705 | } | ||
706 | 590 | ||
707 | retval = si470x_get_register(radio, STATUSRSSI); | 591 | retval = si470x_get_register(radio, STATUSRSSI); |
708 | if (retval < 0) | 592 | if (retval < 0) |
709 | goto done; | 593 | return retval; |
710 | 594 | ||
711 | /* driver constants */ | 595 | /* driver constants */ |
712 | strcpy(tuner->name, "FM"); | 596 | strcpy(tuner->name, "FM"); |
@@ -737,7 +621,7 @@ static int si470x_vidioc_g_tuner(struct file *file, void *priv, | |||
737 | if ((radio->registers[STATUSRSSI] & STATUSRSSI_ST) == 0) | 621 | if ((radio->registers[STATUSRSSI] & STATUSRSSI_ST) == 0) |
738 | tuner->rxsubchans = V4L2_TUNER_SUB_MONO; | 622 | tuner->rxsubchans = V4L2_TUNER_SUB_MONO; |
739 | else | 623 | else |
740 | tuner->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO; | 624 | tuner->rxsubchans = V4L2_TUNER_SUB_STEREO; |
741 | /* If there is a reliable method of detecting an RDS channel, | 625 | /* If there is a reliable method of detecting an RDS channel, |
742 | then this code should check for that before setting this | 626 | then this code should check for that before setting this |
743 | RDS subchannel. */ | 627 | RDS subchannel. */ |
@@ -754,16 +638,13 @@ static int si470x_vidioc_g_tuner(struct file *file, void *priv, | |||
754 | tuner->signal = (radio->registers[STATUSRSSI] & STATUSRSSI_RSSI); | 638 | tuner->signal = (radio->registers[STATUSRSSI] & STATUSRSSI_RSSI); |
755 | /* the ideal factor is 0xffff/75 = 873,8 */ | 639 | /* the ideal factor is 0xffff/75 = 873,8 */ |
756 | tuner->signal = (tuner->signal * 873) + (8 * tuner->signal / 10); | 640 | tuner->signal = (tuner->signal * 873) + (8 * tuner->signal / 10); |
641 | if (tuner->signal > 0xffff) | ||
642 | tuner->signal = 0xffff; | ||
757 | 643 | ||
758 | /* automatic frequency control: -1: freq to low, 1 freq to high */ | 644 | /* automatic frequency control: -1: freq to low, 1 freq to high */ |
759 | /* AFCRL does only indicate that freq. differs, not if too low/high */ | 645 | /* AFCRL does only indicate that freq. differs, not if too low/high */ |
760 | tuner->afc = (radio->registers[STATUSRSSI] & STATUSRSSI_AFCRL) ? 1 : 0; | 646 | tuner->afc = (radio->registers[STATUSRSSI] & STATUSRSSI_AFCRL) ? 1 : 0; |
761 | 647 | ||
762 | done: | ||
763 | if (retval < 0) | ||
764 | dev_warn(&radio->videodev->dev, | ||
765 | "get tuner failed with %d\n", retval); | ||
766 | mutex_unlock(&radio->lock); | ||
767 | return retval; | 648 | return retval; |
768 | } | 649 | } |
769 | 650 | ||
@@ -775,16 +656,9 @@ static int si470x_vidioc_s_tuner(struct file *file, void *priv, | |||
775 | struct v4l2_tuner *tuner) | 656 | struct v4l2_tuner *tuner) |
776 | { | 657 | { |
777 | struct si470x_device *radio = video_drvdata(file); | 658 | struct si470x_device *radio = video_drvdata(file); |
778 | int retval = 0; | ||
779 | |||
780 | mutex_lock(&radio->lock); | ||
781 | /* safety checks */ | ||
782 | retval = si470x_disconnect_check(radio); | ||
783 | if (retval) | ||
784 | goto done; | ||
785 | 659 | ||
786 | if (tuner->index != 0) | 660 | if (tuner->index != 0) |
787 | goto done; | 661 | return -EINVAL; |
788 | 662 | ||
789 | /* mono/stereo selector */ | 663 | /* mono/stereo selector */ |
790 | switch (tuner->audmode) { | 664 | switch (tuner->audmode) { |
@@ -792,20 +666,12 @@ static int si470x_vidioc_s_tuner(struct file *file, void *priv, | |||
792 | radio->registers[POWERCFG] |= POWERCFG_MONO; /* force mono */ | 666 | radio->registers[POWERCFG] |= POWERCFG_MONO; /* force mono */ |
793 | break; | 667 | break; |
794 | case V4L2_TUNER_MODE_STEREO: | 668 | case V4L2_TUNER_MODE_STEREO: |
669 | default: | ||
795 | radio->registers[POWERCFG] &= ~POWERCFG_MONO; /* try stereo */ | 670 | radio->registers[POWERCFG] &= ~POWERCFG_MONO; /* try stereo */ |
796 | break; | 671 | break; |
797 | default: | ||
798 | goto done; | ||
799 | } | 672 | } |
800 | 673 | ||
801 | retval = si470x_set_register(radio, POWERCFG); | 674 | return si470x_set_register(radio, POWERCFG); |
802 | |||
803 | done: | ||
804 | if (retval < 0) | ||
805 | dev_warn(&radio->videodev->dev, | ||
806 | "set tuner failed with %d\n", retval); | ||
807 | mutex_unlock(&radio->lock); | ||
808 | return retval; | ||
809 | } | 675 | } |
810 | 676 | ||
811 | 677 | ||
@@ -816,28 +682,12 @@ static int si470x_vidioc_g_frequency(struct file *file, void *priv, | |||
816 | struct v4l2_frequency *freq) | 682 | struct v4l2_frequency *freq) |
817 | { | 683 | { |
818 | struct si470x_device *radio = video_drvdata(file); | 684 | struct si470x_device *radio = video_drvdata(file); |
819 | int retval = 0; | ||
820 | |||
821 | /* safety checks */ | ||
822 | mutex_lock(&radio->lock); | ||
823 | retval = si470x_disconnect_check(radio); | ||
824 | if (retval) | ||
825 | goto done; | ||
826 | 685 | ||
827 | if (freq->tuner != 0) { | 686 | if (freq->tuner != 0) |
828 | retval = -EINVAL; | 687 | return -EINVAL; |
829 | goto done; | ||
830 | } | ||
831 | 688 | ||
832 | freq->type = V4L2_TUNER_RADIO; | 689 | freq->type = V4L2_TUNER_RADIO; |
833 | retval = si470x_get_freq(radio, &freq->frequency); | 690 | return si470x_get_freq(radio, &freq->frequency); |
834 | |||
835 | done: | ||
836 | if (retval < 0) | ||
837 | dev_warn(&radio->videodev->dev, | ||
838 | "get frequency failed with %d\n", retval); | ||
839 | mutex_unlock(&radio->lock); | ||
840 | return retval; | ||
841 | } | 691 | } |
842 | 692 | ||
843 | 693 | ||
@@ -848,27 +698,11 @@ static int si470x_vidioc_s_frequency(struct file *file, void *priv, | |||
848 | struct v4l2_frequency *freq) | 698 | struct v4l2_frequency *freq) |
849 | { | 699 | { |
850 | struct si470x_device *radio = video_drvdata(file); | 700 | struct si470x_device *radio = video_drvdata(file); |
851 | int retval = 0; | ||
852 | |||
853 | mutex_lock(&radio->lock); | ||
854 | /* safety checks */ | ||
855 | retval = si470x_disconnect_check(radio); | ||
856 | if (retval) | ||
857 | goto done; | ||
858 | 701 | ||
859 | if (freq->tuner != 0) { | 702 | if (freq->tuner != 0) |
860 | retval = -EINVAL; | 703 | return -EINVAL; |
861 | goto done; | ||
862 | } | ||
863 | 704 | ||
864 | retval = si470x_set_freq(radio, freq->frequency); | 705 | return si470x_set_freq(radio, freq->frequency); |
865 | |||
866 | done: | ||
867 | if (retval < 0) | ||
868 | dev_warn(&radio->videodev->dev, | ||
869 | "set frequency failed with %d\n", retval); | ||
870 | mutex_unlock(&radio->lock); | ||
871 | return retval; | ||
872 | } | 706 | } |
873 | 707 | ||
874 | 708 | ||
@@ -879,44 +713,29 @@ static int si470x_vidioc_s_hw_freq_seek(struct file *file, void *priv, | |||
879 | struct v4l2_hw_freq_seek *seek) | 713 | struct v4l2_hw_freq_seek *seek) |
880 | { | 714 | { |
881 | struct si470x_device *radio = video_drvdata(file); | 715 | struct si470x_device *radio = video_drvdata(file); |
882 | int retval = 0; | ||
883 | |||
884 | mutex_lock(&radio->lock); | ||
885 | /* safety checks */ | ||
886 | retval = si470x_disconnect_check(radio); | ||
887 | if (retval) | ||
888 | goto done; | ||
889 | |||
890 | if (seek->tuner != 0) { | ||
891 | retval = -EINVAL; | ||
892 | goto done; | ||
893 | } | ||
894 | 716 | ||
895 | retval = si470x_set_seek(radio, seek->wrap_around, seek->seek_upward); | 717 | if (seek->tuner != 0) |
718 | return -EINVAL; | ||
896 | 719 | ||
897 | done: | 720 | return si470x_set_seek(radio, seek->wrap_around, seek->seek_upward); |
898 | if (retval < 0) | ||
899 | dev_warn(&radio->videodev->dev, | ||
900 | "set hardware frequency seek failed with %d\n", retval); | ||
901 | mutex_unlock(&radio->lock); | ||
902 | return retval; | ||
903 | } | 721 | } |
904 | 722 | ||
723 | const struct v4l2_ctrl_ops si470x_ctrl_ops = { | ||
724 | .s_ctrl = si470x_s_ctrl, | ||
725 | }; | ||
905 | 726 | ||
906 | /* | 727 | /* |
907 | * si470x_ioctl_ops - video device ioctl operations | 728 | * si470x_ioctl_ops - video device ioctl operations |
908 | */ | 729 | */ |
909 | static const struct v4l2_ioctl_ops si470x_ioctl_ops = { | 730 | static const struct v4l2_ioctl_ops si470x_ioctl_ops = { |
910 | .vidioc_querycap = si470x_vidioc_querycap, | 731 | .vidioc_querycap = si470x_vidioc_querycap, |
911 | .vidioc_queryctrl = si470x_vidioc_queryctrl, | ||
912 | .vidioc_g_ctrl = si470x_vidioc_g_ctrl, | ||
913 | .vidioc_s_ctrl = si470x_vidioc_s_ctrl, | ||
914 | .vidioc_g_audio = si470x_vidioc_g_audio, | ||
915 | .vidioc_g_tuner = si470x_vidioc_g_tuner, | 732 | .vidioc_g_tuner = si470x_vidioc_g_tuner, |
916 | .vidioc_s_tuner = si470x_vidioc_s_tuner, | 733 | .vidioc_s_tuner = si470x_vidioc_s_tuner, |
917 | .vidioc_g_frequency = si470x_vidioc_g_frequency, | 734 | .vidioc_g_frequency = si470x_vidioc_g_frequency, |
918 | .vidioc_s_frequency = si470x_vidioc_s_frequency, | 735 | .vidioc_s_frequency = si470x_vidioc_s_frequency, |
919 | .vidioc_s_hw_freq_seek = si470x_vidioc_s_hw_freq_seek, | 736 | .vidioc_s_hw_freq_seek = si470x_vidioc_s_hw_freq_seek, |
737 | .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, | ||
738 | .vidioc_unsubscribe_event = v4l2_event_unsubscribe, | ||
920 | }; | 739 | }; |
921 | 740 | ||
922 | 741 | ||
@@ -926,6 +745,6 @@ static const struct v4l2_ioctl_ops si470x_ioctl_ops = { | |||
926 | struct video_device si470x_viddev_template = { | 745 | struct video_device si470x_viddev_template = { |
927 | .fops = &si470x_fops, | 746 | .fops = &si470x_fops, |
928 | .name = DRIVER_NAME, | 747 | .name = DRIVER_NAME, |
929 | .release = video_device_release, | 748 | .release = video_device_release_empty, |
930 | .ioctl_ops = &si470x_ioctl_ops, | 749 | .ioctl_ops = &si470x_ioctl_ops, |
931 | }; | 750 | }; |