diff options
Diffstat (limited to 'drivers/media/radio')
-rw-r--r-- | drivers/media/radio/si470x/radio-si470x-common.c | 60 | ||||
-rw-r--r-- | drivers/media/radio/si470x/radio-si470x-i2c.c | 63 | ||||
-rw-r--r-- | drivers/media/radio/si470x/radio-si470x.h | 4 | ||||
-rw-r--r-- | drivers/media/radio/wl128x/fmdrv.h | 2 |
4 files changed, 77 insertions, 52 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..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 | */ |
266 | static void si470x_i2c_interrupt_work(struct work_struct *work) | 267 | static 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 | */ | ||
351 | static 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 | ||
354 | end: | ||
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 | */ |
494 | static int si470x_i2c_suspend(struct i2c_client *client, pm_message_t mesg) | 493 | static 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 | */ |
510 | static int si470x_i2c_resume(struct i2c_client *client) | 510 | static 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 | 524 | static 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 | ||
diff --git a/drivers/media/radio/si470x/radio-si470x.h b/drivers/media/radio/si470x/radio-si470x.h index 4a4e908db04c..68da001b09dc 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; |
@@ -179,7 +182,6 @@ struct si470x_device { | |||
179 | 182 | ||
180 | #if defined(CONFIG_I2C_SI470X) || defined(CONFIG_I2C_SI470X_MODULE) | 183 | #if defined(CONFIG_I2C_SI470X) || defined(CONFIG_I2C_SI470X_MODULE) |
181 | struct i2c_client *client; | 184 | struct i2c_client *client; |
182 | struct work_struct radio_work; | ||
183 | #endif | 185 | #endif |
184 | }; | 186 | }; |
185 | 187 | ||
diff --git a/drivers/media/radio/wl128x/fmdrv.h b/drivers/media/radio/wl128x/fmdrv.h index 5db6fd14cf3c..1a45a5d847b0 100644 --- a/drivers/media/radio/wl128x/fmdrv.h +++ b/drivers/media/radio/wl128x/fmdrv.h | |||
@@ -55,8 +55,6 @@ | |||
55 | #define FM_DRV_TX_TIMEOUT (5*HZ) /* 5 seconds */ | 55 | #define FM_DRV_TX_TIMEOUT (5*HZ) /* 5 seconds */ |
56 | #define FM_DRV_RX_SEEK_TIMEOUT (20*HZ) /* 20 seconds */ | 56 | #define FM_DRV_RX_SEEK_TIMEOUT (20*HZ) /* 20 seconds */ |
57 | 57 | ||
58 | #define NO_OF_ENTRIES_IN_ARRAY(array) (sizeof(array) / sizeof(array[0])) | ||
59 | |||
60 | #define fmerr(format, ...) \ | 58 | #define fmerr(format, ...) \ |
61 | printk(KERN_ERR "fmdrv: " format, ## __VA_ARGS__) | 59 | printk(KERN_ERR "fmdrv: " format, ## __VA_ARGS__) |
62 | #define fmwarn(format, ...) \ | 60 | #define fmwarn(format, ...) \ |