aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/radio/radio-mr800.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/radio/radio-mr800.c')
-rw-r--r--drivers/media/radio/radio-mr800.c123
1 files changed, 91 insertions, 32 deletions
diff --git a/drivers/media/radio/radio-mr800.c b/drivers/media/radio/radio-mr800.c
index 256cbeffdcb6..e730eddb2bb5 100644
--- a/drivers/media/radio/radio-mr800.c
+++ b/drivers/media/radio/radio-mr800.c
@@ -72,6 +72,11 @@ MODULE_LICENSE("GPL");
72#define USB_AMRADIO_VENDOR 0x07ca 72#define USB_AMRADIO_VENDOR 0x07ca
73#define USB_AMRADIO_PRODUCT 0xb800 73#define USB_AMRADIO_PRODUCT 0xb800
74 74
75/* dev_warn macro with driver name */
76#define MR800_DRIVER_NAME "radio-mr800"
77#define amradio_dev_warn(dev, fmt, arg...) \
78 dev_warn(dev, MR800_DRIVER_NAME " - " fmt, ##arg)
79
75/* Probably USB_TIMEOUT should be modified in module parameter */ 80/* Probably USB_TIMEOUT should be modified in module parameter */
76#define BUFFER_LENGTH 8 81#define BUFFER_LENGTH 8
77#define USB_TIMEOUT 500 82#define USB_TIMEOUT 500
@@ -154,14 +159,14 @@ MODULE_DEVICE_TABLE(usb, usb_amradio_device_table);
154 159
155/* USB subsystem interface */ 160/* USB subsystem interface */
156static struct usb_driver usb_amradio_driver = { 161static struct usb_driver usb_amradio_driver = {
157 .name = "radio-mr800", 162 .name = MR800_DRIVER_NAME,
158 .probe = usb_amradio_probe, 163 .probe = usb_amradio_probe,
159 .disconnect = usb_amradio_disconnect, 164 .disconnect = usb_amradio_disconnect,
160 .suspend = usb_amradio_suspend, 165 .suspend = usb_amradio_suspend,
161 .resume = usb_amradio_resume, 166 .resume = usb_amradio_resume,
162 .reset_resume = usb_amradio_resume, 167 .reset_resume = usb_amradio_resume,
163 .id_table = usb_amradio_device_table, 168 .id_table = usb_amradio_device_table,
164 .supports_autosuspend = 1, 169 .supports_autosuspend = 0,
165}; 170};
166 171
167/* switch on radio. Send 8 bytes to device. */ 172/* switch on radio. Send 8 bytes to device. */
@@ -202,6 +207,10 @@ static int amradio_stop(struct amradio_device *radio)
202 int retval; 207 int retval;
203 int size; 208 int size;
204 209
210 /* safety check */
211 if (radio->removed)
212 return -EIO;
213
205 mutex_lock(&radio->lock); 214 mutex_lock(&radio->lock);
206 215
207 radio->buffer[0] = 0x00; 216 radio->buffer[0] = 0x00;
@@ -235,6 +244,10 @@ static int amradio_setfreq(struct amradio_device *radio, int freq)
235 int size; 244 int size;
236 unsigned short freq_send = 0x13 + (freq >> 3) / 25; 245 unsigned short freq_send = 0x13 + (freq >> 3) / 25;
237 246
247 /* safety check */
248 if (radio->removed)
249 return -EIO;
250
238 mutex_lock(&radio->lock); 251 mutex_lock(&radio->lock);
239 252
240 radio->buffer[0] = 0x00; 253 radio->buffer[0] = 0x00;
@@ -288,18 +301,12 @@ static void usb_amradio_disconnect(struct usb_interface *intf)
288{ 301{
289 struct amradio_device *radio = usb_get_intfdata(intf); 302 struct amradio_device *radio = usb_get_intfdata(intf);
290 303
291 usb_set_intfdata(intf, NULL); 304 mutex_lock(&radio->lock);
305 radio->removed = 1;
306 mutex_unlock(&radio->lock);
292 307
293 if (radio) { 308 usb_set_intfdata(intf, NULL);
294 video_unregister_device(radio->videodev); 309 video_unregister_device(radio->videodev);
295 radio->videodev = NULL;
296 if (radio->users) {
297 kfree(radio->buffer);
298 kfree(radio);
299 } else {
300 radio->removed = 1;
301 }
302 }
303} 310}
304 311
305/* vidioc_querycap - query device capabilities */ 312/* vidioc_querycap - query device capabilities */
@@ -320,6 +327,10 @@ static int vidioc_g_tuner(struct file *file, void *priv,
320{ 327{
321 struct amradio_device *radio = video_get_drvdata(video_devdata(file)); 328 struct amradio_device *radio = video_get_drvdata(video_devdata(file));
322 329
330 /* safety check */
331 if (radio->removed)
332 return -EIO;
333
323 if (v->index > 0) 334 if (v->index > 0)
324 return -EINVAL; 335 return -EINVAL;
325 336
@@ -346,6 +357,12 @@ static int vidioc_g_tuner(struct file *file, void *priv,
346static int vidioc_s_tuner(struct file *file, void *priv, 357static int vidioc_s_tuner(struct file *file, void *priv,
347 struct v4l2_tuner *v) 358 struct v4l2_tuner *v)
348{ 359{
360 struct amradio_device *radio = video_get_drvdata(video_devdata(file));
361
362 /* safety check */
363 if (radio->removed)
364 return -EIO;
365
349 if (v->index > 0) 366 if (v->index > 0)
350 return -EINVAL; 367 return -EINVAL;
351 return 0; 368 return 0;
@@ -357,9 +374,14 @@ static int vidioc_s_frequency(struct file *file, void *priv,
357{ 374{
358 struct amradio_device *radio = video_get_drvdata(video_devdata(file)); 375 struct amradio_device *radio = video_get_drvdata(video_devdata(file));
359 376
377 /* safety check */
378 if (radio->removed)
379 return -EIO;
380
360 radio->curfreq = f->frequency; 381 radio->curfreq = f->frequency;
361 if (amradio_setfreq(radio, radio->curfreq) < 0) 382 if (amradio_setfreq(radio, radio->curfreq) < 0)
362 warn("Set frequency failed"); 383 amradio_dev_warn(&radio->videodev->dev,
384 "set frequency failed\n");
363 return 0; 385 return 0;
364} 386}
365 387
@@ -369,6 +391,10 @@ static int vidioc_g_frequency(struct file *file, void *priv,
369{ 391{
370 struct amradio_device *radio = video_get_drvdata(video_devdata(file)); 392 struct amradio_device *radio = video_get_drvdata(video_devdata(file));
371 393
394 /* safety check */
395 if (radio->removed)
396 return -EIO;
397
372 f->type = V4L2_TUNER_RADIO; 398 f->type = V4L2_TUNER_RADIO;
373 f->frequency = radio->curfreq; 399 f->frequency = radio->curfreq;
374 return 0; 400 return 0;
@@ -382,8 +408,7 @@ static int vidioc_queryctrl(struct file *file, void *priv,
382 408
383 for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) { 409 for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
384 if (qc->id && qc->id == radio_qctrl[i].id) { 410 if (qc->id && qc->id == radio_qctrl[i].id) {
385 memcpy(qc, &(radio_qctrl[i]), 411 memcpy(qc, &(radio_qctrl[i]), sizeof(*qc));
386 sizeof(*qc));
387 return 0; 412 return 0;
388 } 413 }
389 } 414 }
@@ -396,6 +421,10 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
396{ 421{
397 struct amradio_device *radio = video_get_drvdata(video_devdata(file)); 422 struct amradio_device *radio = video_get_drvdata(video_devdata(file));
398 423
424 /* safety check */
425 if (radio->removed)
426 return -EIO;
427
399 switch (ctrl->id) { 428 switch (ctrl->id) {
400 case V4L2_CID_AUDIO_MUTE: 429 case V4L2_CID_AUDIO_MUTE:
401 ctrl->value = radio->muted; 430 ctrl->value = radio->muted;
@@ -410,16 +439,22 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
410{ 439{
411 struct amradio_device *radio = video_get_drvdata(video_devdata(file)); 440 struct amradio_device *radio = video_get_drvdata(video_devdata(file));
412 441
442 /* safety check */
443 if (radio->removed)
444 return -EIO;
445
413 switch (ctrl->id) { 446 switch (ctrl->id) {
414 case V4L2_CID_AUDIO_MUTE: 447 case V4L2_CID_AUDIO_MUTE:
415 if (ctrl->value) { 448 if (ctrl->value) {
416 if (amradio_stop(radio) < 0) { 449 if (amradio_stop(radio) < 0) {
417 warn("amradio_stop() failed"); 450 amradio_dev_warn(&radio->videodev->dev,
451 "amradio_stop failed\n");
418 return -1; 452 return -1;
419 } 453 }
420 } else { 454 } else {
421 if (amradio_start(radio) < 0) { 455 if (amradio_start(radio) < 0) {
422 warn("amradio_start() failed"); 456 amradio_dev_warn(&radio->videodev->dev,
457 "amradio_start failed\n");
423 return -1; 458 return -1;
424 } 459 }
425 } 460 }
@@ -475,30 +510,38 @@ static int usb_amradio_open(struct inode *inode, struct file *file)
475 radio->muted = 1; 510 radio->muted = 1;
476 511
477 if (amradio_start(radio) < 0) { 512 if (amradio_start(radio) < 0) {
478 warn("Radio did not start up properly"); 513 amradio_dev_warn(&radio->videodev->dev,
514 "radio did not start up properly\n");
479 radio->users = 0; 515 radio->users = 0;
480 unlock_kernel(); 516 unlock_kernel();
481 return -EIO; 517 return -EIO;
482 } 518 }
483 if (amradio_setfreq(radio, radio->curfreq) < 0) 519 if (amradio_setfreq(radio, radio->curfreq) < 0)
484 warn("Set frequency failed"); 520 amradio_dev_warn(&radio->videodev->dev,
521 "set frequency failed\n");
485 522
486 unlock_kernel(); 523 unlock_kernel();
487 return 0; 524 return 0;
488} 525}
489 526
490/*close device - free driver structures */ 527/*close device */
491static int usb_amradio_close(struct inode *inode, struct file *file) 528static int usb_amradio_close(struct inode *inode, struct file *file)
492{ 529{
493 struct amradio_device *radio = video_get_drvdata(video_devdata(file)); 530 struct amradio_device *radio = video_get_drvdata(video_devdata(file));
531 int retval;
494 532
495 if (!radio) 533 if (!radio)
496 return -ENODEV; 534 return -ENODEV;
535
497 radio->users = 0; 536 radio->users = 0;
498 if (radio->removed) { 537
499 kfree(radio->buffer); 538 if (!radio->removed) {
500 kfree(radio); 539 retval = amradio_stop(radio);
540 if (retval < 0)
541 amradio_dev_warn(&radio->videodev->dev,
542 "amradio_stop failed\n");
501 } 543 }
544
502 return 0; 545 return 0;
503} 546}
504 547
@@ -508,9 +551,9 @@ static int usb_amradio_suspend(struct usb_interface *intf, pm_message_t message)
508 struct amradio_device *radio = usb_get_intfdata(intf); 551 struct amradio_device *radio = usb_get_intfdata(intf);
509 552
510 if (amradio_stop(radio) < 0) 553 if (amradio_stop(radio) < 0)
511 warn("amradio_stop() failed"); 554 dev_warn(&intf->dev, "amradio_stop failed\n");
512 555
513 info("radio-mr800: Going into suspend.."); 556 dev_info(&intf->dev, "going into suspend..\n");
514 557
515 return 0; 558 return 0;
516} 559}
@@ -521,9 +564,9 @@ static int usb_amradio_resume(struct usb_interface *intf)
521 struct amradio_device *radio = usb_get_intfdata(intf); 564 struct amradio_device *radio = usb_get_intfdata(intf);
522 565
523 if (amradio_start(radio) < 0) 566 if (amradio_start(radio) < 0)
524 warn("amradio_start() failed"); 567 dev_warn(&intf->dev, "amradio_start failed\n");
525 568
526 info("radio-mr800: Coming out of suspend.."); 569 dev_info(&intf->dev, "coming out of suspend..\n");
527 570
528 return 0; 571 return 0;
529} 572}
@@ -555,12 +598,24 @@ static const struct v4l2_ioctl_ops usb_amradio_ioctl_ops = {
555 .vidioc_s_input = vidioc_s_input, 598 .vidioc_s_input = vidioc_s_input,
556}; 599};
557 600
601static void usb_amradio_device_release(struct video_device *videodev)
602{
603 struct amradio_device *radio = video_get_drvdata(videodev);
604
605 /* we call v4l to free radio->videodev */
606 video_device_release(videodev);
607
608 /* free rest memory */
609 kfree(radio->buffer);
610 kfree(radio);
611}
612
558/* V4L2 interface */ 613/* V4L2 interface */
559static struct video_device amradio_videodev_template = { 614static struct video_device amradio_videodev_template = {
560 .name = "AverMedia MR 800 USB FM Radio", 615 .name = "AverMedia MR 800 USB FM Radio",
561 .fops = &usb_amradio_fops, 616 .fops = &usb_amradio_fops,
562 .ioctl_ops = &usb_amradio_ioctl_ops, 617 .ioctl_ops = &usb_amradio_ioctl_ops,
563 .release = video_device_release, 618 .release = usb_amradio_device_release,
564}; 619};
565 620
566/* check if the device is present and register with v4l and 621/* check if the device is present and register with v4l and
@@ -602,7 +657,7 @@ static int usb_amradio_probe(struct usb_interface *intf,
602 657
603 video_set_drvdata(radio->videodev, radio); 658 video_set_drvdata(radio->videodev, radio);
604 if (video_register_device(radio->videodev, VFL_TYPE_RADIO, radio_nr)) { 659 if (video_register_device(radio->videodev, VFL_TYPE_RADIO, radio_nr)) {
605 warn("Could not register video device"); 660 dev_warn(&intf->dev, "could not register video device\n");
606 video_device_release(radio->videodev); 661 video_device_release(radio->videodev);
607 kfree(radio->buffer); 662 kfree(radio->buffer);
608 kfree(radio); 663 kfree(radio);
@@ -617,9 +672,13 @@ static int __init amradio_init(void)
617{ 672{
618 int retval = usb_register(&usb_amradio_driver); 673 int retval = usb_register(&usb_amradio_driver);
619 674
620 info(DRIVER_VERSION " " DRIVER_DESC); 675 pr_info(KBUILD_MODNAME
676 ": version " DRIVER_VERSION " " DRIVER_DESC "\n");
677
621 if (retval) 678 if (retval)
622 err("usb_register failed. Error number %d", retval); 679 pr_err(KBUILD_MODNAME
680 ": usb_register failed. Error number %d\n", retval);
681
623 return retval; 682 return retval;
624} 683}
625 684