[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:
parent
cc73b4b57c
commit
0830be3fe1
|
@ -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)
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue