aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/radio/si470x/radio-si470x-i2c.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/radio/si470x/radio-si470x-i2c.c')
-rw-r--r--drivers/media/radio/si470x/radio-si470x-i2c.c63
1 files changed, 32 insertions, 31 deletions
diff --git a/drivers/media/radio/si470x/radio-si470x-i2c.c b/drivers/media/radio/si470x/radio-si470x-i2c.c
index 4ce541a5eb47..a2a67772c42c 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);
@@ -261,12 +262,11 @@ int si470x_vidioc_querycap(struct file *file, void *priv,
261 **************************************************************************/ 262 **************************************************************************/
262 263
263/* 264/*
264 * si470x_i2c_interrupt_work - rds processing function 265 * si470x_i2c_interrupt - interrupt handler
265 */ 266 */
266static void si470x_i2c_interrupt_work(struct work_struct *work) 267static irqreturn_t si470x_i2c_interrupt(int irq, void *dev_id)
267{ 268{
268 struct si470x_device *radio = container_of(work, 269 struct si470x_device *radio = dev_id;
269 struct si470x_device, radio_work);
270 unsigned char regnr; 270 unsigned char regnr;
271 unsigned char blocknum; 271 unsigned char blocknum;
272 unsigned short bler; /* rds block errors */ 272 unsigned short bler; /* rds block errors */
@@ -274,21 +274,29 @@ static void si470x_i2c_interrupt_work(struct work_struct *work)
274 unsigned char tmpbuf[3]; 274 unsigned char tmpbuf[3];
275 int retval = 0; 275 int retval = 0;
276 276
277 /* check Seek/Tune Complete */
278 retval = si470x_get_register(radio, STATUSRSSI);
279 if (retval < 0)
280 goto end;
281
282 if (radio->registers[STATUSRSSI] & STATUSRSSI_STC)
283 complete(&radio->completion);
284
277 /* safety checks */ 285 /* safety checks */
278 if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0) 286 if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0)
279 return; 287 goto end;
280 288
281 /* Update RDS registers */ 289 /* Update RDS registers */
282 for (regnr = 0; regnr < RDS_REGISTER_NUM; regnr++) { 290 for (regnr = 1; regnr < RDS_REGISTER_NUM; regnr++) {
283 retval = si470x_get_register(radio, STATUSRSSI + regnr); 291 retval = si470x_get_register(radio, STATUSRSSI + regnr);
284 if (retval < 0) 292 if (retval < 0)
285 return; 293 goto end;
286 } 294 }
287 295
288 /* get rds blocks */ 296 /* get rds blocks */
289 if ((radio->registers[STATUSRSSI] & STATUSRSSI_RDSR) == 0) 297 if ((radio->registers[STATUSRSSI] & STATUSRSSI_RDSR) == 0)
290 /* No RDS group ready, better luck next time */ 298 /* No RDS group ready, better luck next time */
291 return; 299 goto end;
292 300
293 for (blocknum = 0; blocknum < 4; blocknum++) { 301 for (blocknum = 0; blocknum < 4; blocknum++) {
294 switch (blocknum) { 302 switch (blocknum) {
@@ -342,19 +350,8 @@ static void si470x_i2c_interrupt_work(struct work_struct *work)
342 350
343 if (radio->wr_index != radio->rd_index) 351 if (radio->wr_index != radio->rd_index)
344 wake_up_interruptible(&radio->read_queue); 352 wake_up_interruptible(&radio->read_queue);
345}
346
347
348/*
349 * si470x_i2c_interrupt - interrupt handler
350 */
351static irqreturn_t si470x_i2c_interrupt(int irq, void *dev_id)
352{
353 struct si470x_device *radio = dev_id;
354
355 if (!work_pending(&radio->radio_work))
356 schedule_work(&radio->radio_work);
357 353
354end:
358 return IRQ_HANDLED; 355 return IRQ_HANDLED;
359} 356}
360 357
@@ -376,7 +373,6 @@ static int __devinit si470x_i2c_probe(struct i2c_client *client,
376 goto err_initial; 373 goto err_initial;
377 } 374 }
378 375
379 INIT_WORK(&radio->radio_work, si470x_i2c_interrupt_work);
380 radio->users = 0; 376 radio->users = 0;
381 radio->client = client; 377 radio->client = client;
382 mutex_init(&radio->lock); 378 mutex_init(&radio->lock);
@@ -441,7 +437,11 @@ static int __devinit si470x_i2c_probe(struct i2c_client *client,
441 radio->rd_index = 0; 437 radio->rd_index = 0;
442 init_waitqueue_head(&radio->read_queue); 438 init_waitqueue_head(&radio->read_queue);
443 439
444 retval = request_irq(client->irq, si470x_i2c_interrupt, 440 /* mark Seek/Tune Complete Interrupt enabled */
441 radio->stci_enabled = true;
442 init_completion(&radio->completion);
443
444 retval = request_threaded_irq(client->irq, NULL, si470x_i2c_interrupt,
445 IRQF_TRIGGER_FALLING, DRIVER_NAME, radio); 445 IRQF_TRIGGER_FALLING, DRIVER_NAME, radio);
446 if (retval) { 446 if (retval) {
447 dev_err(&client->dev, "Failed to register interrupt\n"); 447 dev_err(&client->dev, "Failed to register interrupt\n");
@@ -479,7 +479,6 @@ static __devexit int si470x_i2c_remove(struct i2c_client *client)
479 struct si470x_device *radio = i2c_get_clientdata(client); 479 struct si470x_device *radio = i2c_get_clientdata(client);
480 480
481 free_irq(client->irq, radio); 481 free_irq(client->irq, radio);
482 cancel_work_sync(&radio->radio_work);
483 video_unregister_device(radio->videodev); 482 video_unregister_device(radio->videodev);
484 kfree(radio); 483 kfree(radio);
485 484
@@ -491,8 +490,9 @@ static __devexit int si470x_i2c_remove(struct i2c_client *client)
491/* 490/*
492 * si470x_i2c_suspend - suspend the device 491 * si470x_i2c_suspend - suspend the device
493 */ 492 */
494static int si470x_i2c_suspend(struct i2c_client *client, pm_message_t mesg) 493static int si470x_i2c_suspend(struct device *dev)
495{ 494{
495 struct i2c_client *client = to_i2c_client(dev);
496 struct si470x_device *radio = i2c_get_clientdata(client); 496 struct si470x_device *radio = i2c_get_clientdata(client);
497 497
498 /* power down */ 498 /* power down */
@@ -507,8 +507,9 @@ static int si470x_i2c_suspend(struct i2c_client *client, pm_message_t mesg)
507/* 507/*
508 * si470x_i2c_resume - resume the device 508 * si470x_i2c_resume - resume the device
509 */ 509 */
510static int si470x_i2c_resume(struct i2c_client *client) 510static int si470x_i2c_resume(struct device *dev)
511{ 511{
512 struct i2c_client *client = to_i2c_client(dev);
512 struct si470x_device *radio = i2c_get_clientdata(client); 513 struct si470x_device *radio = i2c_get_clientdata(client);
513 514
514 /* power up : need 110ms */ 515 /* power up : need 110ms */
@@ -519,9 +520,8 @@ static int si470x_i2c_resume(struct i2c_client *client)
519 520
520 return 0; 521 return 0;
521} 522}
522#else 523
523#define si470x_i2c_suspend NULL 524static SIMPLE_DEV_PM_OPS(si470x_i2c_pm, si470x_i2c_suspend, si470x_i2c_resume);
524#define si470x_i2c_resume NULL
525#endif 525#endif
526 526
527 527
@@ -532,11 +532,12 @@ static struct i2c_driver si470x_i2c_driver = {
532 .driver = { 532 .driver = {
533 .name = "si470x", 533 .name = "si470x",
534 .owner = THIS_MODULE, 534 .owner = THIS_MODULE,
535#ifdef CONFIG_PM
536 .pm = &si470x_i2c_pm,
537#endif
535 }, 538 },
536 .probe = si470x_i2c_probe, 539 .probe = si470x_i2c_probe,
537 .remove = __devexit_p(si470x_i2c_remove), 540 .remove = __devexit_p(si470x_i2c_remove),
538 .suspend = si470x_i2c_suspend,
539 .resume = si470x_i2c_resume,
540 .id_table = si470x_i2c_id, 541 .id_table = si470x_i2c_id,
541}; 542};
542 543