aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/radio
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/radio')
-rw-r--r--drivers/media/radio/si470x/radio-si470x-common.c60
-rw-r--r--drivers/media/radio/si470x/radio-si470x-i2c.c63
-rw-r--r--drivers/media/radio/si470x/radio-si470x.h4
-rw-r--r--drivers/media/radio/wl128x/fmdrv.h2
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 */
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
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, ...) \