[media] radio-si470x: support seek and tune interrupt enable

Currently we use busy waiting to seek and tune, it can replace to
interrupt way. SI470X I2C driver supports interrupt way to week and tune
via this patch.

Signed-off-by: Joonyoung Shim <jy0922.shim@samsung.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
This commit is contained in:
Joonyoung Shim 2011-03-11 03:54:46 -03:00 committed by Mauro Carvalho Chehab
parent cc73b4b57c
commit 0830be3fe1
3 changed files with 60 additions and 20 deletions

View File

@ -174,15 +174,27 @@ static int si470x_set_chan(struct si470x_device *radio, unsigned short chan)
if (retval < 0)
goto done;
/* wait till tune operation has completed */
timeout = jiffies + msecs_to_jiffies(tune_timeout);
do {
retval = si470x_get_register(radio, STATUSRSSI);
if (retval < 0)
goto stop;
timed_out = time_after(jiffies, timeout);
} while (((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0) &&
(!timed_out));
/* currently I2C driver only uses interrupt way to tune */
if (radio->stci_enabled) {
INIT_COMPLETION(radio->completion);
/* wait till tune operation has completed */
retval = wait_for_completion_timeout(&radio->completion,
msecs_to_jiffies(tune_timeout));
if (!retval)
timed_out = true;
} else {
/* wait till tune operation has completed */
timeout = jiffies + msecs_to_jiffies(tune_timeout);
do {
retval = si470x_get_register(radio, STATUSRSSI);
if (retval < 0)
goto stop;
timed_out = time_after(jiffies, timeout);
} while (((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0)
&& (!timed_out));
}
if ((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0)
dev_warn(&radio->videodev->dev, "tune does not complete\n");
if (timed_out)
@ -310,15 +322,27 @@ static int si470x_set_seek(struct si470x_device *radio,
if (retval < 0)
goto done;
/* wait till seek operation has completed */
timeout = jiffies + msecs_to_jiffies(seek_timeout);
do {
retval = si470x_get_register(radio, STATUSRSSI);
if (retval < 0)
goto stop;
timed_out = time_after(jiffies, timeout);
} while (((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0) &&
(!timed_out));
/* currently I2C driver only uses interrupt way to seek */
if (radio->stci_enabled) {
INIT_COMPLETION(radio->completion);
/* wait till seek operation has completed */
retval = wait_for_completion_timeout(&radio->completion,
msecs_to_jiffies(seek_timeout));
if (!retval)
timed_out = true;
} else {
/* wait till seek operation has completed */
timeout = jiffies + msecs_to_jiffies(seek_timeout);
do {
retval = si470x_get_register(radio, STATUSRSSI);
if (retval < 0)
goto stop;
timed_out = time_after(jiffies, timeout);
} while (((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0)
&& (!timed_out));
}
if ((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0)
dev_warn(&radio->videodev->dev, "seek does not complete\n");
if (radio->registers[STATUSRSSI] & STATUSRSSI_SF)

View File

@ -197,8 +197,9 @@ int si470x_fops_open(struct file *file)
if (retval < 0)
goto done;
/* enable RDS interrupt */
/* enable RDS / STC interrupt */
radio->registers[SYSCONFIG1] |= SYSCONFIG1_RDSIEN;
radio->registers[SYSCONFIG1] |= SYSCONFIG1_STCIEN;
radio->registers[SYSCONFIG1] &= ~SYSCONFIG1_GPIO2;
radio->registers[SYSCONFIG1] |= 0x1 << 2;
retval = si470x_set_register(radio, SYSCONFIG1);
@ -274,12 +275,20 @@ static void si470x_i2c_interrupt_work(struct work_struct *work)
unsigned char tmpbuf[3];
int retval = 0;
/* check Seek/Tune Complete */
retval = si470x_get_register(radio, STATUSRSSI);
if (retval < 0)
return;
if (radio->registers[STATUSRSSI] & STATUSRSSI_STC)
complete(&radio->completion);
/* safety checks */
if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0)
return;
/* Update RDS registers */
for (regnr = 0; regnr < RDS_REGISTER_NUM; regnr++) {
for (regnr = 1; regnr < RDS_REGISTER_NUM; regnr++) {
retval = si470x_get_register(radio, STATUSRSSI + regnr);
if (retval < 0)
return;
@ -441,6 +450,10 @@ static int __devinit si470x_i2c_probe(struct i2c_client *client,
radio->rd_index = 0;
init_waitqueue_head(&radio->read_queue);
/* mark Seek/Tune Complete Interrupt enabled */
radio->stci_enabled = true;
init_completion(&radio->completion);
retval = request_irq(client->irq, si470x_i2c_interrupt,
IRQF_TRIGGER_FALLING, DRIVER_NAME, radio);
if (retval) {

View File

@ -158,6 +158,9 @@ struct si470x_device {
unsigned int rd_index;
unsigned int wr_index;
struct completion completion;
bool stci_enabled; /* Seek/Tune Complete Interrupt */
#if defined(CONFIG_USB_SI470X) || defined(CONFIG_USB_SI470X_MODULE)
/* reference to USB and video device */
struct usb_device *usbdev;