aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/radio
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-10-28 12:35:11 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-10-28 12:35:11 -0400
commit0851668fdd97e526b2a41f794b785c204dd3d3e0 (patch)
tree4ef7c20a8be8393006c6fe9627eb29dd30877d61 /drivers/media/radio
parent00ebb6382b8d9c7c15b5f8ad230670d8161d38dd (diff)
parent7655e594945289b418af39f6669fea4666a7b520 (diff)
Merge branch 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6
* 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6: (505 commits) [media] af9015: Fix max I2C message size when used with tda18271 [media] IR: initialize ir_raw_event in few more drivers [media] Guard a divide in v4l1 compat layer [media] imon: fix nomouse modprobe option [media] imon: remove redundant change_protocol call [media] imon: fix my egregious brown paper bag w/rdev/idev split [media] cafe_ccic: Configure ov7670 correctly [media] ov7670: allow configuration of image size, clock speed, and I/O method [media] af9015: support for DigitalNow TinyTwin v3 [1f4d:9016] [media] af9015: map DigitalNow TinyTwin v2 remote [media] DigitalNow TinyTwin remote controller [media] af9015: RC fixes and improvements videodev2.h.xml: Update to reflect the latest changes at videodev2.h [media] v4l: document new Bayer and monochrome pixel formats [media] DocBook/v4l: Add missing formats used on gspca cpia1 and sn9c2028 [media] firedtv: add parameter to fake ca_system_ids in CA_INFO [media] tm6000: fix a macro coding style issue tm6000: Remove some ugly debug code [media] Nova-S-Plus audio line input [media] [RFC,1/1] V4L2: Use new CAP bits in existing RDS capable drivers ...
Diffstat (limited to 'drivers/media/radio')
-rw-r--r--drivers/media/radio/radio-cadet.c3
-rw-r--r--drivers/media/radio/radio-mr800.c75
-rw-r--r--drivers/media/radio/radio-si4713.c12
-rw-r--r--drivers/media/radio/si470x/radio-si470x-common.c29
-rw-r--r--drivers/media/radio/si470x/radio-si470x-usb.c17
-rw-r--r--drivers/media/radio/si470x/radio-si470x.h2
-rw-r--r--drivers/media/radio/si4713-i2c.c2
-rw-r--r--drivers/media/radio/tef6862.c1
8 files changed, 59 insertions, 82 deletions
diff --git a/drivers/media/radio/radio-cadet.c b/drivers/media/radio/radio-cadet.c
index 482d0f3be5ff..b701ea6e7c73 100644
--- a/drivers/media/radio/radio-cadet.c
+++ b/drivers/media/radio/radio-cadet.c
@@ -374,7 +374,8 @@ static int vidioc_g_tuner(struct file *file, void *priv,
374 switch (v->index) { 374 switch (v->index) {
375 case 0: 375 case 0:
376 strlcpy(v->name, "FM", sizeof(v->name)); 376 strlcpy(v->name, "FM", sizeof(v->name));
377 v->capability = V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_RDS; 377 v->capability = V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_RDS |
378 V4L2_TUNER_CAP_RDS_BLOCK_IO;
378 v->rangelow = 1400; /* 87.5 MHz */ 379 v->rangelow = 1400; /* 87.5 MHz */
379 v->rangehigh = 1728; /* 108.0 MHz */ 380 v->rangehigh = 1728; /* 108.0 MHz */
380 v->rxsubchans = cadet_getstereo(dev); 381 v->rxsubchans = cadet_getstereo(dev);
diff --git a/drivers/media/radio/radio-mr800.c b/drivers/media/radio/radio-mr800.c
index 353b82855949..b540e8072e92 100644
--- a/drivers/media/radio/radio-mr800.c
+++ b/drivers/media/radio/radio-mr800.c
@@ -176,8 +176,6 @@ static int amradio_set_mute(struct amradio_device *radio, char argument)
176 int retval; 176 int retval;
177 int size; 177 int size;
178 178
179 BUG_ON(!mutex_is_locked(&radio->lock));
180
181 radio->buffer[0] = 0x00; 179 radio->buffer[0] = 0x00;
182 radio->buffer[1] = 0x55; 180 radio->buffer[1] = 0x55;
183 radio->buffer[2] = 0xaa; 181 radio->buffer[2] = 0xaa;
@@ -207,8 +205,6 @@ static int amradio_setfreq(struct amradio_device *radio, int freq)
207 int size; 205 int size;
208 unsigned short freq_send = 0x10 + (freq >> 3) / 25; 206 unsigned short freq_send = 0x10 + (freq >> 3) / 25;
209 207
210 BUG_ON(!mutex_is_locked(&radio->lock));
211
212 radio->buffer[0] = 0x00; 208 radio->buffer[0] = 0x00;
213 radio->buffer[1] = 0x55; 209 radio->buffer[1] = 0x55;
214 radio->buffer[2] = 0xaa; 210 radio->buffer[2] = 0xaa;
@@ -253,8 +249,6 @@ static int amradio_set_stereo(struct amradio_device *radio, char argument)
253 int retval; 249 int retval;
254 int size; 250 int size;
255 251
256 BUG_ON(!mutex_is_locked(&radio->lock));
257
258 radio->buffer[0] = 0x00; 252 radio->buffer[0] = 0x00;
259 radio->buffer[1] = 0x55; 253 radio->buffer[1] = 0x55;
260 radio->buffer[2] = 0xaa; 254 radio->buffer[2] = 0xaa;
@@ -290,11 +284,13 @@ static void usb_amradio_disconnect(struct usb_interface *intf)
290 struct amradio_device *radio = to_amradio_dev(usb_get_intfdata(intf)); 284 struct amradio_device *radio = to_amradio_dev(usb_get_intfdata(intf));
291 285
292 mutex_lock(&radio->lock); 286 mutex_lock(&radio->lock);
293 radio->usbdev = NULL; 287 /* increase the device node's refcount */
294 mutex_unlock(&radio->lock); 288 get_device(&radio->videodev.dev);
295
296 v4l2_device_disconnect(&radio->v4l2_dev); 289 v4l2_device_disconnect(&radio->v4l2_dev);
297 video_unregister_device(&radio->videodev); 290 video_unregister_device(&radio->videodev);
291 mutex_unlock(&radio->lock);
292 /* decrease the device node's refcount, allowing it to be released */
293 put_device(&radio->videodev.dev);
298} 294}
299 295
300/* vidioc_querycap - query device capabilities */ 296/* vidioc_querycap - query device capabilities */
@@ -503,28 +499,18 @@ out:
503static int usb_amradio_open(struct file *file) 499static int usb_amradio_open(struct file *file)
504{ 500{
505 struct amradio_device *radio = video_drvdata(file); 501 struct amradio_device *radio = video_drvdata(file);
506 int retval = 0; 502 int retval;
507
508 mutex_lock(&radio->lock);
509
510 if (!radio->usbdev) {
511 retval = -EIO;
512 goto unlock;
513 }
514 503
515 file->private_data = radio; 504 file->private_data = radio;
516 retval = usb_autopm_get_interface(radio->intf); 505 retval = usb_autopm_get_interface(radio->intf);
517 if (retval) 506 if (retval)
518 goto unlock; 507 return retval;
519 508
520 if (unlikely(!radio->initialized)) { 509 if (unlikely(!radio->initialized)) {
521 retval = usb_amradio_init(radio); 510 retval = usb_amradio_init(radio);
522 if (retval) 511 if (retval)
523 usb_autopm_put_interface(radio->intf); 512 usb_autopm_put_interface(radio->intf);
524 } 513 }
525
526unlock:
527 mutex_unlock(&radio->lock);
528 return retval; 514 return retval;
529} 515}
530 516
@@ -532,37 +518,10 @@ unlock:
532static int usb_amradio_close(struct file *file) 518static int usb_amradio_close(struct file *file)
533{ 519{
534 struct amradio_device *radio = file->private_data; 520 struct amradio_device *radio = file->private_data;
535 int retval = 0;
536
537 mutex_lock(&radio->lock);
538 521
539 if (!radio->usbdev) 522 if (video_is_registered(&radio->videodev))
540 retval = -EIO;
541 else
542 usb_autopm_put_interface(radio->intf); 523 usb_autopm_put_interface(radio->intf);
543 524 return 0;
544 mutex_unlock(&radio->lock);
545 return retval;
546}
547
548static long usb_amradio_ioctl(struct file *file, unsigned int cmd,
549 unsigned long arg)
550{
551 struct amradio_device *radio = file->private_data;
552 long retval = 0;
553
554 mutex_lock(&radio->lock);
555
556 if (!radio->usbdev) {
557 retval = -EIO;
558 goto unlock;
559 }
560
561 retval = video_ioctl2(file, cmd, arg);
562
563unlock:
564 mutex_unlock(&radio->lock);
565 return retval;
566} 525}
567 526
568/* Suspend device - stop device. Need to be checked and fixed */ 527/* Suspend device - stop device. Need to be checked and fixed */
@@ -571,15 +530,13 @@ static int usb_amradio_suspend(struct usb_interface *intf, pm_message_t message)
571 struct amradio_device *radio = to_amradio_dev(usb_get_intfdata(intf)); 530 struct amradio_device *radio = to_amradio_dev(usb_get_intfdata(intf));
572 531
573 mutex_lock(&radio->lock); 532 mutex_lock(&radio->lock);
574
575 if (!radio->muted && radio->initialized) { 533 if (!radio->muted && radio->initialized) {
576 amradio_set_mute(radio, AMRADIO_STOP); 534 amradio_set_mute(radio, AMRADIO_STOP);
577 radio->muted = 0; 535 radio->muted = 0;
578 } 536 }
537 mutex_unlock(&radio->lock);
579 538
580 dev_info(&intf->dev, "going into suspend..\n"); 539 dev_info(&intf->dev, "going into suspend..\n");
581
582 mutex_unlock(&radio->lock);
583 return 0; 540 return 0;
584} 541}
585 542
@@ -589,7 +546,6 @@ static int usb_amradio_resume(struct usb_interface *intf)
589 struct amradio_device *radio = to_amradio_dev(usb_get_intfdata(intf)); 546 struct amradio_device *radio = to_amradio_dev(usb_get_intfdata(intf));
590 547
591 mutex_lock(&radio->lock); 548 mutex_lock(&radio->lock);
592
593 if (unlikely(!radio->initialized)) 549 if (unlikely(!radio->initialized))
594 goto unlock; 550 goto unlock;
595 551
@@ -604,9 +560,9 @@ static int usb_amradio_resume(struct usb_interface *intf)
604 amradio_set_mute(radio, AMRADIO_START); 560 amradio_set_mute(radio, AMRADIO_START);
605 561
606unlock: 562unlock:
607 dev_info(&intf->dev, "coming out of suspend..\n");
608
609 mutex_unlock(&radio->lock); 563 mutex_unlock(&radio->lock);
564
565 dev_info(&intf->dev, "coming out of suspend..\n");
610 return 0; 566 return 0;
611} 567}
612 568
@@ -615,7 +571,7 @@ static const struct v4l2_file_operations usb_amradio_fops = {
615 .owner = THIS_MODULE, 571 .owner = THIS_MODULE,
616 .open = usb_amradio_open, 572 .open = usb_amradio_open,
617 .release = usb_amradio_close, 573 .release = usb_amradio_close,
618 .ioctl = usb_amradio_ioctl, 574 .unlocked_ioctl = video_ioctl2,
619}; 575};
620 576
621static const struct v4l2_ioctl_ops usb_amradio_ioctl_ops = { 577static const struct v4l2_ioctl_ops usb_amradio_ioctl_ops = {
@@ -671,19 +627,20 @@ static int usb_amradio_probe(struct usb_interface *intf,
671 goto err_v4l2; 627 goto err_v4l2;
672 } 628 }
673 629
630 mutex_init(&radio->lock);
631
674 strlcpy(radio->videodev.name, radio->v4l2_dev.name, 632 strlcpy(radio->videodev.name, radio->v4l2_dev.name,
675 sizeof(radio->videodev.name)); 633 sizeof(radio->videodev.name));
676 radio->videodev.v4l2_dev = &radio->v4l2_dev; 634 radio->videodev.v4l2_dev = &radio->v4l2_dev;
677 radio->videodev.fops = &usb_amradio_fops; 635 radio->videodev.fops = &usb_amradio_fops;
678 radio->videodev.ioctl_ops = &usb_amradio_ioctl_ops; 636 radio->videodev.ioctl_ops = &usb_amradio_ioctl_ops;
679 radio->videodev.release = usb_amradio_video_device_release; 637 radio->videodev.release = usb_amradio_video_device_release;
638 radio->videodev.lock = &radio->lock;
680 639
681 radio->usbdev = interface_to_usbdev(intf); 640 radio->usbdev = interface_to_usbdev(intf);
682 radio->intf = intf; 641 radio->intf = intf;
683 radio->curfreq = 95.16 * FREQ_MUL; 642 radio->curfreq = 95.16 * FREQ_MUL;
684 643
685 mutex_init(&radio->lock);
686
687 video_set_drvdata(&radio->videodev, radio); 644 video_set_drvdata(&radio->videodev, radio);
688 645
689 retval = video_register_device(&radio->videodev, VFL_TYPE_RADIO, 646 retval = video_register_device(&radio->videodev, VFL_TYPE_RADIO,
diff --git a/drivers/media/radio/radio-si4713.c b/drivers/media/radio/radio-si4713.c
index 13554ab13f76..6a435786b63d 100644
--- a/drivers/media/radio/radio-si4713.c
+++ b/drivers/media/radio/radio-si4713.c
@@ -291,19 +291,19 @@ static int radio_si4713_pdriver_probe(struct platform_device *pdev)
291 goto unregister_v4l2_dev; 291 goto unregister_v4l2_dev;
292 } 292 }
293 293
294 sd = v4l2_i2c_new_subdev_board(&rsdev->v4l2_dev, adapter, "si4713_i2c", 294 sd = v4l2_i2c_new_subdev_board(&rsdev->v4l2_dev, adapter, NULL,
295 pdata->subdev_board_info, NULL); 295 pdata->subdev_board_info, NULL);
296 if (!sd) { 296 if (!sd) {
297 dev_err(&pdev->dev, "Cannot get v4l2 subdevice\n"); 297 dev_err(&pdev->dev, "Cannot get v4l2 subdevice\n");
298 rval = -ENODEV; 298 rval = -ENODEV;
299 goto unregister_v4l2_dev; 299 goto put_adapter;
300 } 300 }
301 301
302 rsdev->radio_dev = video_device_alloc(); 302 rsdev->radio_dev = video_device_alloc();
303 if (!rsdev->radio_dev) { 303 if (!rsdev->radio_dev) {
304 dev_err(&pdev->dev, "Failed to alloc video device.\n"); 304 dev_err(&pdev->dev, "Failed to alloc video device.\n");
305 rval = -ENOMEM; 305 rval = -ENOMEM;
306 goto unregister_v4l2_dev; 306 goto put_adapter;
307 } 307 }
308 308
309 memcpy(rsdev->radio_dev, &radio_si4713_vdev_template, 309 memcpy(rsdev->radio_dev, &radio_si4713_vdev_template,
@@ -320,6 +320,8 @@ static int radio_si4713_pdriver_probe(struct platform_device *pdev)
320 320
321free_vdev: 321free_vdev:
322 video_device_release(rsdev->radio_dev); 322 video_device_release(rsdev->radio_dev);
323put_adapter:
324 i2c_put_adapter(adapter);
323unregister_v4l2_dev: 325unregister_v4l2_dev:
324 v4l2_device_unregister(&rsdev->v4l2_dev); 326 v4l2_device_unregister(&rsdev->v4l2_dev);
325free_rsdev: 327free_rsdev:
@@ -335,8 +337,12 @@ static int __exit radio_si4713_pdriver_remove(struct platform_device *pdev)
335 struct radio_si4713_device *rsdev = container_of(v4l2_dev, 337 struct radio_si4713_device *rsdev = container_of(v4l2_dev,
336 struct radio_si4713_device, 338 struct radio_si4713_device,
337 v4l2_dev); 339 v4l2_dev);
340 struct v4l2_subdev *sd = list_entry(v4l2_dev->subdevs.next,
341 struct v4l2_subdev, list);
342 struct i2c_client *client = v4l2_get_subdevdata(sd);
338 343
339 video_unregister_device(rsdev->radio_dev); 344 video_unregister_device(rsdev->radio_dev);
345 i2c_put_adapter(client->adapter);
340 v4l2_device_unregister(&rsdev->v4l2_dev); 346 v4l2_device_unregister(&rsdev->v4l2_dev);
341 kfree(rsdev); 347 kfree(rsdev);
342 348
diff --git a/drivers/media/radio/si470x/radio-si470x-common.c b/drivers/media/radio/si470x/radio-si470x-common.c
index 9927a595b426..ac76dfe5b3fa 100644
--- a/drivers/media/radio/si470x/radio-si470x-common.c
+++ b/drivers/media/radio/si470x/radio-si470x-common.c
@@ -408,17 +408,15 @@ done:
408/* 408/*
409 * si470x_rds_on - switch on rds reception 409 * si470x_rds_on - switch on rds reception
410 */ 410 */
411int si470x_rds_on(struct si470x_device *radio) 411static int si470x_rds_on(struct si470x_device *radio)
412{ 412{
413 int retval; 413 int retval;
414 414
415 /* sysconfig 1 */ 415 /* sysconfig 1 */
416 mutex_lock(&radio->lock);
417 radio->registers[SYSCONFIG1] |= SYSCONFIG1_RDS; 416 radio->registers[SYSCONFIG1] |= SYSCONFIG1_RDS;
418 retval = si470x_set_register(radio, SYSCONFIG1); 417 retval = si470x_set_register(radio, SYSCONFIG1);
419 if (retval < 0) 418 if (retval < 0)
420 radio->registers[SYSCONFIG1] &= ~SYSCONFIG1_RDS; 419 radio->registers[SYSCONFIG1] &= ~SYSCONFIG1_RDS;
421 mutex_unlock(&radio->lock);
422 420
423 return retval; 421 return retval;
424} 422}
@@ -440,6 +438,7 @@ static ssize_t si470x_fops_read(struct file *file, char __user *buf,
440 unsigned int block_count = 0; 438 unsigned int block_count = 0;
441 439
442 /* switch on rds reception */ 440 /* switch on rds reception */
441 mutex_lock(&radio->lock);
443 if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0) 442 if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0)
444 si470x_rds_on(radio); 443 si470x_rds_on(radio);
445 444
@@ -480,9 +479,9 @@ static ssize_t si470x_fops_read(struct file *file, char __user *buf,
480 buf += 3; 479 buf += 3;
481 retval += 3; 480 retval += 3;
482 } 481 }
483 mutex_unlock(&radio->lock);
484 482
485done: 483done:
484 mutex_unlock(&radio->lock);
486 return retval; 485 return retval;
487} 486}
488 487
@@ -497,8 +496,11 @@ static unsigned int si470x_fops_poll(struct file *file,
497 int retval = 0; 496 int retval = 0;
498 497
499 /* switch on rds reception */ 498 /* switch on rds reception */
499
500 mutex_lock(&radio->lock);
500 if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0) 501 if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0)
501 si470x_rds_on(radio); 502 si470x_rds_on(radio);
503 mutex_unlock(&radio->lock);
502 504
503 poll_wait(file, &radio->read_queue, pts); 505 poll_wait(file, &radio->read_queue, pts);
504 506
@@ -516,7 +518,7 @@ static const struct v4l2_file_operations si470x_fops = {
516 .owner = THIS_MODULE, 518 .owner = THIS_MODULE,
517 .read = si470x_fops_read, 519 .read = si470x_fops_read,
518 .poll = si470x_fops_poll, 520 .poll = si470x_fops_poll,
519 .ioctl = video_ioctl2, 521 .unlocked_ioctl = video_ioctl2,
520 .open = si470x_fops_open, 522 .open = si470x_fops_open,
521 .release = si470x_fops_release, 523 .release = si470x_fops_release,
522}; 524};
@@ -572,6 +574,7 @@ static int si470x_vidioc_g_ctrl(struct file *file, void *priv,
572 struct si470x_device *radio = video_drvdata(file); 574 struct si470x_device *radio = video_drvdata(file);
573 int retval = 0; 575 int retval = 0;
574 576
577 mutex_lock(&radio->lock);
575 /* safety checks */ 578 /* safety checks */
576 retval = si470x_disconnect_check(radio); 579 retval = si470x_disconnect_check(radio);
577 if (retval) 580 if (retval)
@@ -594,6 +597,8 @@ done:
594 if (retval < 0) 597 if (retval < 0)
595 dev_warn(&radio->videodev->dev, 598 dev_warn(&radio->videodev->dev,
596 "get control failed with %d\n", retval); 599 "get control failed with %d\n", retval);
600
601 mutex_unlock(&radio->lock);
597 return retval; 602 return retval;
598} 603}
599 604
@@ -607,6 +612,7 @@ static int si470x_vidioc_s_ctrl(struct file *file, void *priv,
607 struct si470x_device *radio = video_drvdata(file); 612 struct si470x_device *radio = video_drvdata(file);
608 int retval = 0; 613 int retval = 0;
609 614
615 mutex_lock(&radio->lock);
610 /* safety checks */ 616 /* safety checks */
611 retval = si470x_disconnect_check(radio); 617 retval = si470x_disconnect_check(radio);
612 if (retval) 618 if (retval)
@@ -633,6 +639,7 @@ done:
633 if (retval < 0) 639 if (retval < 0)
634 dev_warn(&radio->videodev->dev, 640 dev_warn(&radio->videodev->dev,
635 "set control failed with %d\n", retval); 641 "set control failed with %d\n", retval);
642 mutex_unlock(&radio->lock);
636 return retval; 643 return retval;
637} 644}
638 645
@@ -662,6 +669,7 @@ static int si470x_vidioc_g_tuner(struct file *file, void *priv,
662 struct si470x_device *radio = video_drvdata(file); 669 struct si470x_device *radio = video_drvdata(file);
663 int retval = 0; 670 int retval = 0;
664 671
672 mutex_lock(&radio->lock);
665 /* safety checks */ 673 /* safety checks */
666 retval = si470x_disconnect_check(radio); 674 retval = si470x_disconnect_check(radio);
667 if (retval) 675 if (retval)
@@ -681,7 +689,7 @@ static int si470x_vidioc_g_tuner(struct file *file, void *priv,
681 tuner->type = V4L2_TUNER_RADIO; 689 tuner->type = V4L2_TUNER_RADIO;
682#if defined(CONFIG_USB_SI470X) || defined(CONFIG_USB_SI470X_MODULE) 690#if defined(CONFIG_USB_SI470X) || defined(CONFIG_USB_SI470X_MODULE)
683 tuner->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO | 691 tuner->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO |
684 V4L2_TUNER_CAP_RDS; 692 V4L2_TUNER_CAP_RDS | V4L2_TUNER_CAP_RDS_BLOCK_IO;
685#else 693#else
686 tuner->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO; 694 tuner->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO;
687#endif 695#endif
@@ -737,6 +745,7 @@ done:
737 if (retval < 0) 745 if (retval < 0)
738 dev_warn(&radio->videodev->dev, 746 dev_warn(&radio->videodev->dev,
739 "get tuner failed with %d\n", retval); 747 "get tuner failed with %d\n", retval);
748 mutex_unlock(&radio->lock);
740 return retval; 749 return retval;
741} 750}
742 751
@@ -750,6 +759,7 @@ static int si470x_vidioc_s_tuner(struct file *file, void *priv,
750 struct si470x_device *radio = video_drvdata(file); 759 struct si470x_device *radio = video_drvdata(file);
751 int retval = 0; 760 int retval = 0;
752 761
762 mutex_lock(&radio->lock);
753 /* safety checks */ 763 /* safety checks */
754 retval = si470x_disconnect_check(radio); 764 retval = si470x_disconnect_check(radio);
755 if (retval) 765 if (retval)
@@ -776,6 +786,7 @@ done:
776 if (retval < 0) 786 if (retval < 0)
777 dev_warn(&radio->videodev->dev, 787 dev_warn(&radio->videodev->dev,
778 "set tuner failed with %d\n", retval); 788 "set tuner failed with %d\n", retval);
789 mutex_unlock(&radio->lock);
779 return retval; 790 return retval;
780} 791}
781 792
@@ -790,6 +801,7 @@ static int si470x_vidioc_g_frequency(struct file *file, void *priv,
790 int retval = 0; 801 int retval = 0;
791 802
792 /* safety checks */ 803 /* safety checks */
804 mutex_lock(&radio->lock);
793 retval = si470x_disconnect_check(radio); 805 retval = si470x_disconnect_check(radio);
794 if (retval) 806 if (retval)
795 goto done; 807 goto done;
@@ -806,6 +818,7 @@ done:
806 if (retval < 0) 818 if (retval < 0)
807 dev_warn(&radio->videodev->dev, 819 dev_warn(&radio->videodev->dev,
808 "get frequency failed with %d\n", retval); 820 "get frequency failed with %d\n", retval);
821 mutex_unlock(&radio->lock);
809 return retval; 822 return retval;
810} 823}
811 824
@@ -819,6 +832,7 @@ static int si470x_vidioc_s_frequency(struct file *file, void *priv,
819 struct si470x_device *radio = video_drvdata(file); 832 struct si470x_device *radio = video_drvdata(file);
820 int retval = 0; 833 int retval = 0;
821 834
835 mutex_lock(&radio->lock);
822 /* safety checks */ 836 /* safety checks */
823 retval = si470x_disconnect_check(radio); 837 retval = si470x_disconnect_check(radio);
824 if (retval) 838 if (retval)
@@ -835,6 +849,7 @@ done:
835 if (retval < 0) 849 if (retval < 0)
836 dev_warn(&radio->videodev->dev, 850 dev_warn(&radio->videodev->dev,
837 "set frequency failed with %d\n", retval); 851 "set frequency failed with %d\n", retval);
852 mutex_unlock(&radio->lock);
838 return retval; 853 return retval;
839} 854}
840 855
@@ -848,6 +863,7 @@ static int si470x_vidioc_s_hw_freq_seek(struct file *file, void *priv,
848 struct si470x_device *radio = video_drvdata(file); 863 struct si470x_device *radio = video_drvdata(file);
849 int retval = 0; 864 int retval = 0;
850 865
866 mutex_lock(&radio->lock);
851 /* safety checks */ 867 /* safety checks */
852 retval = si470x_disconnect_check(radio); 868 retval = si470x_disconnect_check(radio);
853 if (retval) 869 if (retval)
@@ -864,6 +880,7 @@ done:
864 if (retval < 0) 880 if (retval < 0)
865 dev_warn(&radio->videodev->dev, 881 dev_warn(&radio->videodev->dev,
866 "set hardware frequency seek failed with %d\n", retval); 882 "set hardware frequency seek failed with %d\n", retval);
883 mutex_unlock(&radio->lock);
867 return retval; 884 return retval;
868} 885}
869 886
diff --git a/drivers/media/radio/si470x/radio-si470x-usb.c b/drivers/media/radio/si470x/radio-si470x-usb.c
index 5ec13e50a9f0..392e84fe90ef 100644
--- a/drivers/media/radio/si470x/radio-si470x-usb.c
+++ b/drivers/media/radio/si470x/radio-si470x-usb.c
@@ -517,7 +517,7 @@ int si470x_fops_open(struct file *file)
517 struct si470x_device *radio = video_drvdata(file); 517 struct si470x_device *radio = video_drvdata(file);
518 int retval; 518 int retval;
519 519
520 lock_kernel(); 520 mutex_lock(&radio->lock);
521 radio->users++; 521 radio->users++;
522 522
523 retval = usb_autopm_get_interface(radio->intf); 523 retval = usb_autopm_get_interface(radio->intf);
@@ -558,7 +558,7 @@ int si470x_fops_open(struct file *file)
558 } 558 }
559 559
560done: 560done:
561 unlock_kernel(); 561 mutex_unlock(&radio->lock);
562 return retval; 562 return retval;
563} 563}
564 564
@@ -577,7 +577,7 @@ int si470x_fops_release(struct file *file)
577 goto done; 577 goto done;
578 } 578 }
579 579
580 mutex_lock(&radio->disconnect_lock); 580 mutex_lock(&radio->lock);
581 radio->users--; 581 radio->users--;
582 if (radio->users == 0) { 582 if (radio->users == 0) {
583 /* shutdown interrupt handler */ 583 /* shutdown interrupt handler */
@@ -591,7 +591,7 @@ int si470x_fops_release(struct file *file)
591 video_unregister_device(radio->videodev); 591 video_unregister_device(radio->videodev);
592 kfree(radio->int_in_buffer); 592 kfree(radio->int_in_buffer);
593 kfree(radio->buffer); 593 kfree(radio->buffer);
594 mutex_unlock(&radio->disconnect_lock); 594 mutex_unlock(&radio->lock);
595 kfree(radio); 595 kfree(radio);
596 goto done; 596 goto done;
597 } 597 }
@@ -603,7 +603,7 @@ int si470x_fops_release(struct file *file)
603 retval = si470x_stop(radio); 603 retval = si470x_stop(radio);
604 usb_autopm_put_interface(radio->intf); 604 usb_autopm_put_interface(radio->intf);
605 } 605 }
606 mutex_unlock(&radio->disconnect_lock); 606 mutex_unlock(&radio->lock);
607done: 607done:
608 return retval; 608 return retval;
609} 609}
@@ -661,7 +661,6 @@ static int si470x_usb_driver_probe(struct usb_interface *intf,
661 radio->disconnected = 0; 661 radio->disconnected = 0;
662 radio->usbdev = interface_to_usbdev(intf); 662 radio->usbdev = interface_to_usbdev(intf);
663 radio->intf = intf; 663 radio->intf = intf;
664 mutex_init(&radio->disconnect_lock);
665 mutex_init(&radio->lock); 664 mutex_init(&radio->lock);
666 665
667 iface_desc = intf->cur_altsetting; 666 iface_desc = intf->cur_altsetting;
@@ -830,7 +829,7 @@ static void si470x_usb_driver_disconnect(struct usb_interface *intf)
830{ 829{
831 struct si470x_device *radio = usb_get_intfdata(intf); 830 struct si470x_device *radio = usb_get_intfdata(intf);
832 831
833 mutex_lock(&radio->disconnect_lock); 832 mutex_lock(&radio->lock);
834 radio->disconnected = 1; 833 radio->disconnected = 1;
835 usb_set_intfdata(intf, NULL); 834 usb_set_intfdata(intf, NULL);
836 if (radio->users == 0) { 835 if (radio->users == 0) {
@@ -843,10 +842,10 @@ static void si470x_usb_driver_disconnect(struct usb_interface *intf)
843 kfree(radio->int_in_buffer); 842 kfree(radio->int_in_buffer);
844 video_unregister_device(radio->videodev); 843 video_unregister_device(radio->videodev);
845 kfree(radio->buffer); 844 kfree(radio->buffer);
846 mutex_unlock(&radio->disconnect_lock); 845 mutex_unlock(&radio->lock);
847 kfree(radio); 846 kfree(radio);
848 } else { 847 } else {
849 mutex_unlock(&radio->disconnect_lock); 848 mutex_unlock(&radio->lock);
850 } 849 }
851} 850}
852 851
diff --git a/drivers/media/radio/si470x/radio-si470x.h b/drivers/media/radio/si470x/radio-si470x.h
index 3cd0a29cd6e7..ea12782359a0 100644
--- a/drivers/media/radio/si470x/radio-si470x.h
+++ b/drivers/media/radio/si470x/radio-si470x.h
@@ -177,7 +177,6 @@ struct si470x_device {
177 177
178 /* driver management */ 178 /* driver management */
179 unsigned char disconnected; 179 unsigned char disconnected;
180 struct mutex disconnect_lock;
181#endif 180#endif
182 181
183#if defined(CONFIG_I2C_SI470X) || defined(CONFIG_I2C_SI470X_MODULE) 182#if defined(CONFIG_I2C_SI470X) || defined(CONFIG_I2C_SI470X_MODULE)
@@ -221,7 +220,6 @@ int si470x_disconnect_check(struct si470x_device *radio);
221int si470x_set_freq(struct si470x_device *radio, unsigned int freq); 220int si470x_set_freq(struct si470x_device *radio, unsigned int freq);
222int si470x_start(struct si470x_device *radio); 221int si470x_start(struct si470x_device *radio);
223int si470x_stop(struct si470x_device *radio); 222int si470x_stop(struct si470x_device *radio);
224int si470x_rds_on(struct si470x_device *radio);
225int si470x_fops_open(struct file *file); 223int si470x_fops_open(struct file *file);
226int si470x_fops_release(struct file *file); 224int si470x_fops_release(struct file *file);
227int si470x_vidioc_querycap(struct file *file, void *priv, 225int si470x_vidioc_querycap(struct file *file, void *priv,
diff --git a/drivers/media/radio/si4713-i2c.c b/drivers/media/radio/si4713-i2c.c
index fc7f4b794649..a6e6f1987a3a 100644
--- a/drivers/media/radio/si4713-i2c.c
+++ b/drivers/media/radio/si4713-i2c.c
@@ -1804,7 +1804,7 @@ static int si4713_g_modulator(struct v4l2_subdev *sd, struct v4l2_modulator *vm)
1804 1804
1805 strncpy(vm->name, "FM Modulator", 32); 1805 strncpy(vm->name, "FM Modulator", 32);
1806 vm->capability = V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LOW | 1806 vm->capability = V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LOW |
1807 V4L2_TUNER_CAP_RDS; 1807 V4L2_TUNER_CAP_RDS | V4L2_TUNER_CAP_RDS_CONTROLS;
1808 1808
1809 /* Report current frequency range limits */ 1809 /* Report current frequency range limits */
1810 vm->rangelow = si4713_to_v4l2(FREQ_RANGE_LOW); 1810 vm->rangelow = si4713_to_v4l2(FREQ_RANGE_LOW);
diff --git a/drivers/media/radio/tef6862.c b/drivers/media/radio/tef6862.c
index 90cae90277e7..7c0d77751f6e 100644
--- a/drivers/media/radio/tef6862.c
+++ b/drivers/media/radio/tef6862.c
@@ -22,7 +22,6 @@
22#include <linux/kernel.h> 22#include <linux/kernel.h>
23#include <linux/interrupt.h> 23#include <linux/interrupt.h>
24#include <linux/i2c.h> 24#include <linux/i2c.h>
25#include <linux/i2c-id.h>
26#include <linux/slab.h> 25#include <linux/slab.h>
27#include <media/v4l2-ioctl.h> 26#include <media/v4l2-ioctl.h>
28#include <media/v4l2-device.h> 27#include <media/v4l2-device.h>