aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/radio/dsbr100.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/radio/dsbr100.c')
-rw-r--r--drivers/media/radio/dsbr100.c128
1 files changed, 38 insertions, 90 deletions
diff --git a/drivers/media/radio/dsbr100.c b/drivers/media/radio/dsbr100.c
index ed9cd7ad060..3d8cc425fa6 100644
--- a/drivers/media/radio/dsbr100.c
+++ b/drivers/media/radio/dsbr100.c
@@ -129,7 +129,7 @@ devices, that would be 76 and 91. */
129#define STARTED 0 129#define STARTED 0
130#define STOPPED 1 130#define STOPPED 1
131 131
132#define videodev_to_radio(d) container_of(d, struct dsbr100_device, videodev) 132#define v4l2_dev_to_radio(d) container_of(d, struct dsbr100_device, v4l2_dev)
133 133
134static int usb_dsbr100_probe(struct usb_interface *intf, 134static int usb_dsbr100_probe(struct usb_interface *intf,
135 const struct usb_device_id *id); 135 const struct usb_device_id *id);
@@ -148,10 +148,9 @@ struct dsbr100_device {
148 struct v4l2_device v4l2_dev; 148 struct v4l2_device v4l2_dev;
149 149
150 u8 *transfer_buffer; 150 u8 *transfer_buffer;
151 struct mutex lock; /* buffer locking */ 151 struct mutex v4l2_lock;
152 int curfreq; 152 int curfreq;
153 int stereo; 153 int stereo;
154 int removed;
155 int status; 154 int status;
156}; 155};
157 156
@@ -182,8 +181,6 @@ static int dsbr100_start(struct dsbr100_device *radio)
182 int retval; 181 int retval;
183 int request; 182 int request;
184 183
185 mutex_lock(&radio->lock);
186
187 retval = usb_control_msg(radio->usbdev, 184 retval = usb_control_msg(radio->usbdev,
188 usb_rcvctrlpipe(radio->usbdev, 0), 185 usb_rcvctrlpipe(radio->usbdev, 0),
189 USB_REQ_GET_STATUS, 186 USB_REQ_GET_STATUS,
@@ -207,11 +204,9 @@ static int dsbr100_start(struct dsbr100_device *radio)
207 } 204 }
208 205
209 radio->status = STARTED; 206 radio->status = STARTED;
210 mutex_unlock(&radio->lock);
211 return (radio->transfer_buffer)[0]; 207 return (radio->transfer_buffer)[0];
212 208
213usb_control_msg_failed: 209usb_control_msg_failed:
214 mutex_unlock(&radio->lock);
215 dev_err(&radio->usbdev->dev, 210 dev_err(&radio->usbdev->dev,
216 "%s - usb_control_msg returned %i, request %i\n", 211 "%s - usb_control_msg returned %i, request %i\n",
217 __func__, retval, request); 212 __func__, retval, request);
@@ -225,8 +220,6 @@ static int dsbr100_stop(struct dsbr100_device *radio)
225 int retval; 220 int retval;
226 int request; 221 int request;
227 222
228 mutex_lock(&radio->lock);
229
230 retval = usb_control_msg(radio->usbdev, 223 retval = usb_control_msg(radio->usbdev,
231 usb_rcvctrlpipe(radio->usbdev, 0), 224 usb_rcvctrlpipe(radio->usbdev, 0),
232 USB_REQ_GET_STATUS, 225 USB_REQ_GET_STATUS,
@@ -250,11 +243,9 @@ static int dsbr100_stop(struct dsbr100_device *radio)
250 } 243 }
251 244
252 radio->status = STOPPED; 245 radio->status = STOPPED;
253 mutex_unlock(&radio->lock);
254 return (radio->transfer_buffer)[0]; 246 return (radio->transfer_buffer)[0];
255 247
256usb_control_msg_failed: 248usb_control_msg_failed:
257 mutex_unlock(&radio->lock);
258 dev_err(&radio->usbdev->dev, 249 dev_err(&radio->usbdev->dev,
259 "%s - usb_control_msg returned %i, request %i\n", 250 "%s - usb_control_msg returned %i, request %i\n",
260 __func__, retval, request); 251 __func__, retval, request);
@@ -269,8 +260,6 @@ static int dsbr100_setfreq(struct dsbr100_device *radio)
269 int request; 260 int request;
270 int freq = (radio->curfreq / 16 * 80) / 1000 + 856; 261 int freq = (radio->curfreq / 16 * 80) / 1000 + 856;
271 262
272 mutex_lock(&radio->lock);
273
274 retval = usb_control_msg(radio->usbdev, 263 retval = usb_control_msg(radio->usbdev,
275 usb_rcvctrlpipe(radio->usbdev, 0), 264 usb_rcvctrlpipe(radio->usbdev, 0),
276 DSB100_TUNE, 265 DSB100_TUNE,
@@ -306,12 +295,10 @@ static int dsbr100_setfreq(struct dsbr100_device *radio)
306 } 295 }
307 296
308 radio->stereo = !((radio->transfer_buffer)[0] & 0x01); 297 radio->stereo = !((radio->transfer_buffer)[0] & 0x01);
309 mutex_unlock(&radio->lock);
310 return (radio->transfer_buffer)[0]; 298 return (radio->transfer_buffer)[0];
311 299
312usb_control_msg_failed: 300usb_control_msg_failed:
313 radio->stereo = -1; 301 radio->stereo = -1;
314 mutex_unlock(&radio->lock);
315 dev_err(&radio->usbdev->dev, 302 dev_err(&radio->usbdev->dev,
316 "%s - usb_control_msg returned %i, request %i\n", 303 "%s - usb_control_msg returned %i, request %i\n",
317 __func__, retval, request); 304 __func__, retval, request);
@@ -324,8 +311,6 @@ static void dsbr100_getstat(struct dsbr100_device *radio)
324{ 311{
325 int retval; 312 int retval;
326 313
327 mutex_lock(&radio->lock);
328
329 retval = usb_control_msg(radio->usbdev, 314 retval = usb_control_msg(radio->usbdev,
330 usb_rcvctrlpipe(radio->usbdev, 0), 315 usb_rcvctrlpipe(radio->usbdev, 0),
331 USB_REQ_GET_STATUS, 316 USB_REQ_GET_STATUS,
@@ -340,33 +325,8 @@ static void dsbr100_getstat(struct dsbr100_device *radio)
340 } else { 325 } else {
341 radio->stereo = !(radio->transfer_buffer[0] & 0x01); 326 radio->stereo = !(radio->transfer_buffer[0] & 0x01);
342 } 327 }
343
344 mutex_unlock(&radio->lock);
345} 328}
346 329
347/* USB subsystem interface begins here */
348
349/*
350 * Handle unplugging of the device.
351 * We call video_unregister_device in any case.
352 * The last function called in this procedure is
353 * usb_dsbr100_video_device_release
354 */
355static void usb_dsbr100_disconnect(struct usb_interface *intf)
356{
357 struct dsbr100_device *radio = usb_get_intfdata(intf);
358
359 usb_set_intfdata (intf, NULL);
360
361 mutex_lock(&radio->lock);
362 radio->removed = 1;
363 mutex_unlock(&radio->lock);
364
365 video_unregister_device(&radio->videodev);
366 v4l2_device_disconnect(&radio->v4l2_dev);
367}
368
369
370static int vidioc_querycap(struct file *file, void *priv, 330static int vidioc_querycap(struct file *file, void *priv,
371 struct v4l2_capability *v) 331 struct v4l2_capability *v)
372{ 332{
@@ -385,10 +345,6 @@ static int vidioc_g_tuner(struct file *file, void *priv,
385{ 345{
386 struct dsbr100_device *radio = video_drvdata(file); 346 struct dsbr100_device *radio = video_drvdata(file);
387 347
388 /* safety check */
389 if (radio->removed)
390 return -EIO;
391
392 if (v->index > 0) 348 if (v->index > 0)
393 return -EINVAL; 349 return -EINVAL;
394 350
@@ -410,16 +366,7 @@ static int vidioc_g_tuner(struct file *file, void *priv,
410static int vidioc_s_tuner(struct file *file, void *priv, 366static int vidioc_s_tuner(struct file *file, void *priv,
411 struct v4l2_tuner *v) 367 struct v4l2_tuner *v)
412{ 368{
413 struct dsbr100_device *radio = video_drvdata(file); 369 return v->index ? -EINVAL : 0;
414
415 /* safety check */
416 if (radio->removed)
417 return -EIO;
418
419 if (v->index > 0)
420 return -EINVAL;
421
422 return 0;
423} 370}
424 371
425static int vidioc_s_frequency(struct file *file, void *priv, 372static int vidioc_s_frequency(struct file *file, void *priv,
@@ -428,13 +375,7 @@ static int vidioc_s_frequency(struct file *file, void *priv,
428 struct dsbr100_device *radio = video_drvdata(file); 375 struct dsbr100_device *radio = video_drvdata(file);
429 int retval; 376 int retval;
430 377
431 /* safety check */
432 if (radio->removed)
433 return -EIO;
434
435 mutex_lock(&radio->lock);
436 radio->curfreq = f->frequency; 378 radio->curfreq = f->frequency;
437 mutex_unlock(&radio->lock);
438 379
439 retval = dsbr100_setfreq(radio); 380 retval = dsbr100_setfreq(radio);
440 if (retval < 0) 381 if (retval < 0)
@@ -447,10 +388,6 @@ static int vidioc_g_frequency(struct file *file, void *priv,
447{ 388{
448 struct dsbr100_device *radio = video_drvdata(file); 389 struct dsbr100_device *radio = video_drvdata(file);
449 390
450 /* safety check */
451 if (radio->removed)
452 return -EIO;
453
454 f->type = V4L2_TUNER_RADIO; 391 f->type = V4L2_TUNER_RADIO;
455 f->frequency = radio->curfreq; 392 f->frequency = radio->curfreq;
456 return 0; 393 return 0;
@@ -472,10 +409,6 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
472{ 409{
473 struct dsbr100_device *radio = video_drvdata(file); 410 struct dsbr100_device *radio = video_drvdata(file);
474 411
475 /* safety check */
476 if (radio->removed)
477 return -EIO;
478
479 switch (ctrl->id) { 412 switch (ctrl->id) {
480 case V4L2_CID_AUDIO_MUTE: 413 case V4L2_CID_AUDIO_MUTE:
481 ctrl->value = radio->status; 414 ctrl->value = radio->status;
@@ -490,10 +423,6 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
490 struct dsbr100_device *radio = video_drvdata(file); 423 struct dsbr100_device *radio = video_drvdata(file);
491 int retval; 424 int retval;
492 425
493 /* safety check */
494 if (radio->removed)
495 return -EIO;
496
497 switch (ctrl->id) { 426 switch (ctrl->id) {
498 case V4L2_CID_AUDIO_MUTE: 427 case V4L2_CID_AUDIO_MUTE:
499 if (ctrl->value) { 428 if (ctrl->value) {
@@ -535,25 +464,44 @@ static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
535 464
536static int vidioc_s_input(struct file *filp, void *priv, unsigned int i) 465static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
537{ 466{
538 if (i != 0) 467 return i ? -EINVAL : 0;
539 return -EINVAL;
540 return 0;
541} 468}
542 469
543static int vidioc_s_audio(struct file *file, void *priv, 470static int vidioc_s_audio(struct file *file, void *priv,
544 struct v4l2_audio *a) 471 struct v4l2_audio *a)
545{ 472{
546 if (a->index != 0) 473 return a->index ? -EINVAL : 0;
547 return -EINVAL; 474}
548 return 0; 475
476/* USB subsystem interface begins here */
477
478/*
479 * Handle unplugging of the device.
480 * We call video_unregister_device in any case.
481 * The last function called in this procedure is
482 * usb_dsbr100_video_device_release
483 */
484static void usb_dsbr100_disconnect(struct usb_interface *intf)
485{
486 struct dsbr100_device *radio = usb_get_intfdata(intf);
487
488 v4l2_device_get(&radio->v4l2_dev);
489 mutex_lock(&radio->v4l2_lock);
490 usb_set_intfdata(intf, NULL);
491 video_unregister_device(&radio->videodev);
492 v4l2_device_disconnect(&radio->v4l2_dev);
493 mutex_unlock(&radio->v4l2_lock);
494 v4l2_device_put(&radio->v4l2_dev);
549} 495}
550 496
497
551/* Suspend device - stop device. */ 498/* Suspend device - stop device. */
552static int usb_dsbr100_suspend(struct usb_interface *intf, pm_message_t message) 499static int usb_dsbr100_suspend(struct usb_interface *intf, pm_message_t message)
553{ 500{
554 struct dsbr100_device *radio = usb_get_intfdata(intf); 501 struct dsbr100_device *radio = usb_get_intfdata(intf);
555 int retval; 502 int retval;
556 503
504 mutex_lock(&radio->v4l2_lock);
557 if (radio->status == STARTED) { 505 if (radio->status == STARTED) {
558 retval = dsbr100_stop(radio); 506 retval = dsbr100_stop(radio);
559 if (retval < 0) 507 if (retval < 0)
@@ -564,11 +512,9 @@ static int usb_dsbr100_suspend(struct usb_interface *intf, pm_message_t message)
564 * we set status equal to STARTED. 512 * we set status equal to STARTED.
565 * On resume we will check status and run radio if needed. 513 * On resume we will check status and run radio if needed.
566 */ 514 */
567
568 mutex_lock(&radio->lock);
569 radio->status = STARTED; 515 radio->status = STARTED;
570 mutex_unlock(&radio->lock);
571 } 516 }
517 mutex_unlock(&radio->v4l2_lock);
572 518
573 dev_info(&intf->dev, "going into suspend..\n"); 519 dev_info(&intf->dev, "going into suspend..\n");
574 520
@@ -581,11 +527,13 @@ static int usb_dsbr100_resume(struct usb_interface *intf)
581 struct dsbr100_device *radio = usb_get_intfdata(intf); 527 struct dsbr100_device *radio = usb_get_intfdata(intf);
582 int retval; 528 int retval;
583 529
530 mutex_lock(&radio->v4l2_lock);
584 if (radio->status == STARTED) { 531 if (radio->status == STARTED) {
585 retval = dsbr100_start(radio); 532 retval = dsbr100_start(radio);
586 if (retval < 0) 533 if (retval < 0)
587 dev_warn(&intf->dev, "dsbr100_start failed\n"); 534 dev_warn(&intf->dev, "dsbr100_start failed\n");
588 } 535 }
536 mutex_unlock(&radio->v4l2_lock);
589 537
590 dev_info(&intf->dev, "coming out of suspend..\n"); 538 dev_info(&intf->dev, "coming out of suspend..\n");
591 539
@@ -593,9 +541,9 @@ static int usb_dsbr100_resume(struct usb_interface *intf)
593} 541}
594 542
595/* free data structures */ 543/* free data structures */
596static void usb_dsbr100_video_device_release(struct video_device *videodev) 544static void usb_dsbr100_release(struct v4l2_device *v4l2_dev)
597{ 545{
598 struct dsbr100_device *radio = videodev_to_radio(videodev); 546 struct dsbr100_device *radio = v4l2_dev_to_radio(v4l2_dev);
599 547
600 v4l2_device_unregister(&radio->v4l2_dev); 548 v4l2_device_unregister(&radio->v4l2_dev);
601 kfree(radio->transfer_buffer); 549 kfree(radio->transfer_buffer);
@@ -605,7 +553,7 @@ static void usb_dsbr100_video_device_release(struct video_device *videodev)
605/* File system interface */ 553/* File system interface */
606static const struct v4l2_file_operations usb_dsbr100_fops = { 554static const struct v4l2_file_operations usb_dsbr100_fops = {
607 .owner = THIS_MODULE, 555 .owner = THIS_MODULE,
608 .ioctl = video_ioctl2, 556 .unlocked_ioctl = video_ioctl2,
609}; 557};
610 558
611static const struct v4l2_ioctl_ops usb_dsbr100_ioctl_ops = { 559static const struct v4l2_ioctl_ops usb_dsbr100_ioctl_ops = {
@@ -644,6 +592,7 @@ static int usb_dsbr100_probe(struct usb_interface *intf,
644 } 592 }
645 593
646 v4l2_dev = &radio->v4l2_dev; 594 v4l2_dev = &radio->v4l2_dev;
595 v4l2_dev->release = usb_dsbr100_release;
647 596
648 retval = v4l2_device_register(&intf->dev, v4l2_dev); 597 retval = v4l2_device_register(&intf->dev, v4l2_dev);
649 if (retval < 0) { 598 if (retval < 0) {
@@ -653,15 +602,14 @@ static int usb_dsbr100_probe(struct usb_interface *intf,
653 return retval; 602 return retval;
654 } 603 }
655 604
605 mutex_init(&radio->v4l2_lock);
656 strlcpy(radio->videodev.name, v4l2_dev->name, sizeof(radio->videodev.name)); 606 strlcpy(radio->videodev.name, v4l2_dev->name, sizeof(radio->videodev.name));
657 radio->videodev.v4l2_dev = v4l2_dev; 607 radio->videodev.v4l2_dev = v4l2_dev;
658 radio->videodev.fops = &usb_dsbr100_fops; 608 radio->videodev.fops = &usb_dsbr100_fops;
659 radio->videodev.ioctl_ops = &usb_dsbr100_ioctl_ops; 609 radio->videodev.ioctl_ops = &usb_dsbr100_ioctl_ops;
660 radio->videodev.release = usb_dsbr100_video_device_release; 610 radio->videodev.release = video_device_release_empty;
661 611 radio->videodev.lock = &radio->v4l2_lock;
662 mutex_init(&radio->lock);
663 612
664 radio->removed = 0;
665 radio->usbdev = interface_to_usbdev(intf); 613 radio->usbdev = interface_to_usbdev(intf);
666 radio->curfreq = FREQ_MIN * FREQ_MUL; 614 radio->curfreq = FREQ_MIN * FREQ_MUL;
667 radio->status = STOPPED; 615 radio->status = STOPPED;