aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/radio
diff options
context:
space:
mode:
authorTobias Lorenz <tobias.lorenz@gmx.net>2008-05-31 14:11:32 -0400
committerMauro Carvalho Chehab <mchehab@infradead.org>2008-07-20 06:08:43 -0400
commitbbc8995f9fa3f9cdd77aeb7c9bbf5bf526feca3c (patch)
tree21e354bf284b7430e49ccd19abf1971f7ffc62fa /drivers/media/radio
parentace7d4bbe6170ef9b72bfa82c3e5769d250fffae (diff)
V4L/DVB (7997): si470x: hardware frequency seek support
This patch brings the following changes: - this now finally adds hardware frequency seek support Signed-off-by: Tobias Lorenz <tobias.lorenz@gmx.net> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media/radio')
-rw-r--r--drivers/media/radio/radio-si470x.c97
1 files changed, 95 insertions, 2 deletions
diff --git a/drivers/media/radio/radio-si470x.c b/drivers/media/radio/radio-si470x.c
index db9d64a228b..dc93a882b38 100644
--- a/drivers/media/radio/radio-si470x.c
+++ b/drivers/media/radio/radio-si470x.c
@@ -101,11 +101,11 @@
101 * - unplugging fixed 101 * - unplugging fixed
102 * 2008-05-07 Tobias Lorenz <tobias.lorenz@gmx.net> 102 * 2008-05-07 Tobias Lorenz <tobias.lorenz@gmx.net>
103 * Version 1.0.8 103 * Version 1.0.8
104 * - hardware frequency seek support
104 * - afc indication 105 * - afc indication
105 * - more safety checks, let si470x_get_freq return errno 106 * - more safety checks, let si470x_get_freq return errno
106 * 107 *
107 * ToDo: 108 * ToDo:
108 * - add seeking support
109 * - add firmware download/update support 109 * - add firmware download/update support
110 * - RDS support: interrupt mode, instead of polling 110 * - RDS support: interrupt mode, instead of polling
111 * - add LED status output (check if that's not already done in firmware) 111 * - add LED status output (check if that's not already done in firmware)
@@ -192,6 +192,11 @@ static unsigned int tune_timeout = 3000;
192module_param(tune_timeout, uint, 0); 192module_param(tune_timeout, uint, 0);
193MODULE_PARM_DESC(tune_timeout, "Tune timeout: *3000*"); 193MODULE_PARM_DESC(tune_timeout, "Tune timeout: *3000*");
194 194
195/* Seek timeout */
196static unsigned int seek_timeout = 5000;
197module_param(seek_timeout, uint, 0);
198MODULE_PARM_DESC(seek_timeout, "Seek timeout: *5000*");
199
195/* RDS buffer blocks */ 200/* RDS buffer blocks */
196static unsigned int rds_buf = 100; 201static unsigned int rds_buf = 100;
197module_param(rds_buf, uint, 0); 202module_param(rds_buf, uint, 0);
@@ -727,6 +732,62 @@ static int si470x_set_freq(struct si470x_device *radio, unsigned int freq)
727 732
728 733
729/* 734/*
735 * si470x_set_seek - set seek
736 */
737static int si470x_set_seek(struct si470x_device *radio,
738 unsigned int wrap_around, unsigned int seek_upward)
739{
740 int retval = 0;
741 unsigned long timeout;
742 bool timed_out = 0;
743
744 /* start seeking */
745 radio->registers[POWERCFG] |= POWERCFG_SEEK;
746 if (wrap_around == 1)
747 radio->registers[POWERCFG] &= ~POWERCFG_SKMODE;
748 else
749 radio->registers[POWERCFG] |= POWERCFG_SKMODE;
750 if (seek_upward == 1)
751 radio->registers[POWERCFG] |= POWERCFG_SEEKUP;
752 else
753 radio->registers[POWERCFG] &= ~POWERCFG_SEEKUP;
754 retval = si470x_set_register(radio, POWERCFG);
755 if (retval < 0)
756 goto done;
757
758 /* wait till seek operation has completed */
759 timeout = jiffies + msecs_to_jiffies(seek_timeout);
760 do {
761 retval = si470x_get_register(radio, STATUSRSSI);
762 if (retval < 0)
763 goto stop;
764 timed_out = time_after(jiffies, timeout);
765 } while (((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0) &&
766 (!timed_out));
767 if ((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0)
768 printk(KERN_WARNING DRIVER_NAME ": seek does not complete\n");
769 if (radio->registers[STATUSRSSI] & STATUSRSSI_SF)
770 printk(KERN_WARNING DRIVER_NAME
771 ": seek failed / band limit reached\n");
772 if (timed_out)
773 printk(KERN_WARNING DRIVER_NAME
774 ": seek timed out after %u ms\n", seek_timeout);
775
776stop:
777 /* stop seeking */
778 radio->registers[POWERCFG] &= ~POWERCFG_SEEK;
779 retval = si470x_set_register(radio, POWERCFG);
780
781done:
782 /* try again, if timed out */
783 if ((retval == 0) && timed_out)
784 retval = -EAGAIN;
785
786 return retval;
787}
788
789
790/*
730 * si470x_start - switch on radio 791 * si470x_start - switch on radio
731 */ 792 */
732static int si470x_start(struct si470x_device *radio) 793static int si470x_start(struct si470x_device *radio)
@@ -1148,7 +1209,8 @@ static int si470x_vidioc_querycap(struct file *file, void *priv,
1148 strlcpy(capability->card, DRIVER_CARD, sizeof(capability->card)); 1209 strlcpy(capability->card, DRIVER_CARD, sizeof(capability->card));
1149 sprintf(capability->bus_info, "USB"); 1210 sprintf(capability->bus_info, "USB");
1150 capability->version = DRIVER_KERNEL_VERSION; 1211 capability->version = DRIVER_KERNEL_VERSION;
1151 capability->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO; 1212 capability->capabilities = V4L2_CAP_HW_FREQ_SEEK |
1213 V4L2_CAP_TUNER | V4L2_CAP_RADIO;
1152 1214
1153 return 0; 1215 return 0;
1154} 1216}
@@ -1495,6 +1557,36 @@ done:
1495 1557
1496 1558
1497/* 1559/*
1560 * si470x_vidioc_s_hw_freq_seek - set hardware frequency seek
1561 */
1562static int si470x_vidioc_s_hw_freq_seek(struct file *file, void *priv,
1563 struct v4l2_hw_freq_seek *seek)
1564{
1565 struct si470x_device *radio = video_get_drvdata(video_devdata(file));
1566 int retval = 0;
1567
1568 /* safety checks */
1569 if (radio->disconnected) {
1570 retval = -EIO;
1571 goto done;
1572 }
1573 if ((seek->tuner != 0) && (seek->type != V4L2_TUNER_RADIO)) {
1574 retval = -EINVAL;
1575 goto done;
1576 }
1577
1578 retval = si470x_set_seek(radio, seek->wrap_around, seek->seek_upward);
1579
1580done:
1581 if (retval < 0)
1582 printk(KERN_WARNING DRIVER_NAME
1583 ": set hardware frequency seek failed with %d\n",
1584 retval);
1585 return retval;
1586}
1587
1588
1589/*
1498 * si470x_viddev_tamples - video device interface 1590 * si470x_viddev_tamples - video device interface
1499 */ 1591 */
1500static struct video_device si470x_viddev_template = { 1592static struct video_device si470x_viddev_template = {
@@ -1514,6 +1606,7 @@ static struct video_device si470x_viddev_template = {
1514 .vidioc_s_tuner = si470x_vidioc_s_tuner, 1606 .vidioc_s_tuner = si470x_vidioc_s_tuner,
1515 .vidioc_g_frequency = si470x_vidioc_g_frequency, 1607 .vidioc_g_frequency = si470x_vidioc_g_frequency,
1516 .vidioc_s_frequency = si470x_vidioc_s_frequency, 1608 .vidioc_s_frequency = si470x_vidioc_s_frequency,
1609 .vidioc_s_hw_freq_seek = si470x_vidioc_s_hw_freq_seek,
1517 .owner = THIS_MODULE, 1610 .owner = THIS_MODULE,
1518}; 1611};
1519 1612