diff options
Diffstat (limited to 'drivers/media/radio/si470x')
-rw-r--r-- | drivers/media/radio/si470x/radio-si470x-common.c | 60 | ||||
-rw-r--r-- | drivers/media/radio/si470x/radio-si470x-i2c.c | 17 | ||||
-rw-r--r-- | drivers/media/radio/si470x/radio-si470x.h | 3 |
3 files changed, 60 insertions, 20 deletions
diff --git a/drivers/media/radio/si470x/radio-si470x-common.c b/drivers/media/radio/si470x/radio-si470x-common.c index 38ae6cd65790..0e740c98786c 100644 --- a/drivers/media/radio/si470x/radio-si470x-common.c +++ b/drivers/media/radio/si470x/radio-si470x-common.c | |||
@@ -174,15 +174,27 @@ static int si470x_set_chan(struct si470x_device *radio, unsigned short chan) | |||
174 | if (retval < 0) | 174 | if (retval < 0) |
175 | goto done; | 175 | goto done; |
176 | 176 | ||
177 | /* wait till tune operation has completed */ | 177 | /* currently I2C driver only uses interrupt way to tune */ |
178 | timeout = jiffies + msecs_to_jiffies(tune_timeout); | 178 | if (radio->stci_enabled) { |
179 | do { | 179 | INIT_COMPLETION(radio->completion); |
180 | retval = si470x_get_register(radio, STATUSRSSI); | 180 | |
181 | if (retval < 0) | 181 | /* wait till tune operation has completed */ |
182 | goto stop; | 182 | retval = wait_for_completion_timeout(&radio->completion, |
183 | timed_out = time_after(jiffies, timeout); | 183 | msecs_to_jiffies(tune_timeout)); |
184 | } while (((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0) && | 184 | if (!retval) |
185 | (!timed_out)); | 185 | timed_out = true; |
186 | } else { | ||
187 | /* wait till tune operation has completed */ | ||
188 | timeout = jiffies + msecs_to_jiffies(tune_timeout); | ||
189 | do { | ||
190 | retval = si470x_get_register(radio, STATUSRSSI); | ||
191 | if (retval < 0) | ||
192 | goto stop; | ||
193 | timed_out = time_after(jiffies, timeout); | ||
194 | } while (((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0) | ||
195 | && (!timed_out)); | ||
196 | } | ||
197 | |||
186 | if ((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0) | 198 | if ((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0) |
187 | dev_warn(&radio->videodev->dev, "tune does not complete\n"); | 199 | dev_warn(&radio->videodev->dev, "tune does not complete\n"); |
188 | if (timed_out) | 200 | if (timed_out) |
@@ -310,15 +322,27 @@ static int si470x_set_seek(struct si470x_device *radio, | |||
310 | if (retval < 0) | 322 | if (retval < 0) |
311 | goto done; | 323 | goto done; |
312 | 324 | ||
313 | /* wait till seek operation has completed */ | 325 | /* currently I2C driver only uses interrupt way to seek */ |
314 | timeout = jiffies + msecs_to_jiffies(seek_timeout); | 326 | if (radio->stci_enabled) { |
315 | do { | 327 | INIT_COMPLETION(radio->completion); |
316 | retval = si470x_get_register(radio, STATUSRSSI); | 328 | |
317 | if (retval < 0) | 329 | /* wait till seek operation has completed */ |
318 | goto stop; | 330 | retval = wait_for_completion_timeout(&radio->completion, |
319 | timed_out = time_after(jiffies, timeout); | 331 | msecs_to_jiffies(seek_timeout)); |
320 | } while (((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0) && | 332 | if (!retval) |
321 | (!timed_out)); | 333 | timed_out = true; |
334 | } else { | ||
335 | /* wait till seek operation has completed */ | ||
336 | timeout = jiffies + msecs_to_jiffies(seek_timeout); | ||
337 | do { | ||
338 | retval = si470x_get_register(radio, STATUSRSSI); | ||
339 | if (retval < 0) | ||
340 | goto stop; | ||
341 | timed_out = time_after(jiffies, timeout); | ||
342 | } while (((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0) | ||
343 | && (!timed_out)); | ||
344 | } | ||
345 | |||
322 | if ((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0) | 346 | if ((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0) |
323 | dev_warn(&radio->videodev->dev, "seek does not complete\n"); | 347 | dev_warn(&radio->videodev->dev, "seek does not complete\n"); |
324 | if (radio->registers[STATUSRSSI] & STATUSRSSI_SF) | 348 | if (radio->registers[STATUSRSSI] & STATUSRSSI_SF) |
diff --git a/drivers/media/radio/si470x/radio-si470x-i2c.c b/drivers/media/radio/si470x/radio-si470x-i2c.c index 4ce541a5eb47..5a2975ded5d2 100644 --- a/drivers/media/radio/si470x/radio-si470x-i2c.c +++ b/drivers/media/radio/si470x/radio-si470x-i2c.c | |||
@@ -197,8 +197,9 @@ int si470x_fops_open(struct file *file) | |||
197 | if (retval < 0) | 197 | if (retval < 0) |
198 | goto done; | 198 | goto done; |
199 | 199 | ||
200 | /* enable RDS interrupt */ | 200 | /* enable RDS / STC interrupt */ |
201 | radio->registers[SYSCONFIG1] |= SYSCONFIG1_RDSIEN; | 201 | radio->registers[SYSCONFIG1] |= SYSCONFIG1_RDSIEN; |
202 | radio->registers[SYSCONFIG1] |= SYSCONFIG1_STCIEN; | ||
202 | radio->registers[SYSCONFIG1] &= ~SYSCONFIG1_GPIO2; | 203 | radio->registers[SYSCONFIG1] &= ~SYSCONFIG1_GPIO2; |
203 | radio->registers[SYSCONFIG1] |= 0x1 << 2; | 204 | radio->registers[SYSCONFIG1] |= 0x1 << 2; |
204 | retval = si470x_set_register(radio, SYSCONFIG1); | 205 | retval = si470x_set_register(radio, SYSCONFIG1); |
@@ -274,12 +275,20 @@ static void si470x_i2c_interrupt_work(struct work_struct *work) | |||
274 | unsigned char tmpbuf[3]; | 275 | unsigned char tmpbuf[3]; |
275 | int retval = 0; | 276 | int retval = 0; |
276 | 277 | ||
278 | /* check Seek/Tune Complete */ | ||
279 | retval = si470x_get_register(radio, STATUSRSSI); | ||
280 | if (retval < 0) | ||
281 | return; | ||
282 | |||
283 | if (radio->registers[STATUSRSSI] & STATUSRSSI_STC) | ||
284 | complete(&radio->completion); | ||
285 | |||
277 | /* safety checks */ | 286 | /* safety checks */ |
278 | if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0) | 287 | if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0) |
279 | return; | 288 | return; |
280 | 289 | ||
281 | /* Update RDS registers */ | 290 | /* Update RDS registers */ |
282 | for (regnr = 0; regnr < RDS_REGISTER_NUM; regnr++) { | 291 | for (regnr = 1; regnr < RDS_REGISTER_NUM; regnr++) { |
283 | retval = si470x_get_register(radio, STATUSRSSI + regnr); | 292 | retval = si470x_get_register(radio, STATUSRSSI + regnr); |
284 | if (retval < 0) | 293 | if (retval < 0) |
285 | return; | 294 | return; |
@@ -441,6 +450,10 @@ static int __devinit si470x_i2c_probe(struct i2c_client *client, | |||
441 | radio->rd_index = 0; | 450 | radio->rd_index = 0; |
442 | init_waitqueue_head(&radio->read_queue); | 451 | init_waitqueue_head(&radio->read_queue); |
443 | 452 | ||
453 | /* mark Seek/Tune Complete Interrupt enabled */ | ||
454 | radio->stci_enabled = true; | ||
455 | init_completion(&radio->completion); | ||
456 | |||
444 | retval = request_irq(client->irq, si470x_i2c_interrupt, | 457 | retval = request_irq(client->irq, si470x_i2c_interrupt, |
445 | IRQF_TRIGGER_FALLING, DRIVER_NAME, radio); | 458 | IRQF_TRIGGER_FALLING, DRIVER_NAME, radio); |
446 | if (retval) { | 459 | if (retval) { |
diff --git a/drivers/media/radio/si470x/radio-si470x.h b/drivers/media/radio/si470x/radio-si470x.h index 4a4e908db04c..9ef671657771 100644 --- a/drivers/media/radio/si470x/radio-si470x.h +++ b/drivers/media/radio/si470x/radio-si470x.h | |||
@@ -158,6 +158,9 @@ struct si470x_device { | |||
158 | unsigned int rd_index; | 158 | unsigned int rd_index; |
159 | unsigned int wr_index; | 159 | unsigned int wr_index; |
160 | 160 | ||
161 | struct completion completion; | ||
162 | bool stci_enabled; /* Seek/Tune Complete Interrupt */ | ||
163 | |||
161 | #if defined(CONFIG_USB_SI470X) || defined(CONFIG_USB_SI470X_MODULE) | 164 | #if defined(CONFIG_USB_SI470X) || defined(CONFIG_USB_SI470X_MODULE) |
162 | /* reference to USB and video device */ | 165 | /* reference to USB and video device */ |
163 | struct usb_device *usbdev; | 166 | struct usb_device *usbdev; |