V4L/DVB (11956): dsbr100: no need to pass curfreq value to dsbr100_setfreq()
[linux-2.6.git] / drivers / media / radio / dsbr100.c
1 /* A driver for the D-Link DSB-R100 USB radio and Gemtek USB Radio 21.
2  The device plugs into both the USB and an analog audio input, so this thing
3  only deals with initialisation and frequency setting, the
4  audio data has to be handled by a sound driver.
5
6  Major issue: I can't find out where the device reports the signal
7  strength, and indeed the windows software appearantly just looks
8  at the stereo indicator as well.  So, scanning will only find
9  stereo stations.  Sad, but I can't help it.
10
11  Also, the windows program sends oodles of messages over to the
12  device, and I couldn't figure out their meaning.  My suspicion
13  is that they don't have any:-)
14
15  You might find some interesting stuff about this module at
16  http://unimut.fsk.uni-heidelberg.de/unimut/demi/dsbr
17
18  Copyright (c) 2000 Markus Demleitner <msdemlei@cl.uni-heidelberg.de>
19
20  This program is free software; you can redistribute it and/or modify
21  it under the terms of the GNU General Public License as published by
22  the Free Software Foundation; either version 2 of the License, or
23  (at your option) any later version.
24
25  This program is distributed in the hope that it will be useful,
26  but WITHOUT ANY WARRANTY; without even the implied warranty of
27  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
28  GNU General Public License for more details.
29
30  You should have received a copy of the GNU General Public License
31  along with this program; if not, write to the Free Software
32  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
33
34  History:
35
36  Version 0.45:
37         Converted to v4l2_device.
38
39  Version 0.44:
40         Add suspend/resume functions, fix unplug of device,
41         a lot of cleanups and fixes by Alexey Klimov <klimov.linux@gmail.com>
42
43  Version 0.43:
44         Oliver Neukum: avoided DMA coherency issue
45
46  Version 0.42:
47         Converted dsbr100 to use video_ioctl2
48         by Douglas Landgraf <dougsland@gmail.com>
49
50  Version 0.41-ac1:
51         Alan Cox: Some cleanups and fixes
52
53  Version 0.41:
54         Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org>
55
56  Version 0.40:
57         Markus: Updates for 2.6.x kernels, code layout changes, name sanitizing
58
59  Version 0.30:
60         Markus: Updates for 2.5.x kernel and more ISO compliant source
61
62  Version 0.25:
63         PSL and Markus: Cleanup, radio now doesn't stop on device close
64
65  Version 0.24:
66         Markus: Hope I got these silly VIDEO_TUNER_LOW issues finally
67         right.  Some minor cleanup, improved standalone compilation
68
69  Version 0.23:
70         Markus: Sign extension bug fixed by declaring transfer_buffer unsigned
71
72  Version 0.22:
73         Markus: Some (brown bag) cleanup in what VIDIOCSTUNER returns,
74         thanks to Mike Cox for pointing the problem out.
75
76  Version 0.21:
77         Markus: Minor cleanup, warnings if something goes wrong, lame attempt
78         to adhere to Documentation/CodingStyle
79
80  Version 0.2:
81         Brad Hards <bradh@dynamite.com.au>: Fixes to make it work as non-module
82         Markus: Copyright clarification
83
84  Version 0.01: Markus: initial release
85
86 */
87
88 #include <linux/kernel.h>
89 #include <linux/module.h>
90 #include <linux/init.h>
91 #include <linux/slab.h>
92 #include <linux/input.h>
93 #include <linux/videodev2.h>
94 #include <media/v4l2-device.h>
95 #include <media/v4l2-ioctl.h>
96 #include <linux/usb.h>
97
98 /*
99  * Version Information
100  */
101 #include <linux/version.h>      /* for KERNEL_VERSION MACRO     */
102
103 #define DRIVER_VERSION "v0.45"
104 #define RADIO_VERSION KERNEL_VERSION(0, 4, 5)
105
106 #define DRIVER_AUTHOR "Markus Demleitner <msdemlei@tucana.harvard.edu>"
107 #define DRIVER_DESC "D-Link DSB-R100 USB FM radio driver"
108
109 #define DSB100_VENDOR 0x04b4
110 #define DSB100_PRODUCT 0x1002
111
112 /* Commands the device appears to understand */
113 #define DSB100_TUNE 1
114 #define DSB100_ONOFF 2
115
116 #define TB_LEN 16
117
118 /* Frequency limits in MHz -- these are European values.  For Japanese
119 devices, that would be 76 and 91.  */
120 #define FREQ_MIN  87.5
121 #define FREQ_MAX 108.0
122 #define FREQ_MUL 16000
123
124 #define videodev_to_radio(d) container_of(d, struct dsbr100_device, videodev)
125
126 static int usb_dsbr100_probe(struct usb_interface *intf,
127                              const struct usb_device_id *id);
128 static void usb_dsbr100_disconnect(struct usb_interface *intf);
129 static int usb_dsbr100_suspend(struct usb_interface *intf,
130                                                 pm_message_t message);
131 static int usb_dsbr100_resume(struct usb_interface *intf);
132
133 static int radio_nr = -1;
134 module_param(radio_nr, int, 0);
135
136 /* Data for one (physical) device */
137 struct dsbr100_device {
138         struct usb_device *usbdev;
139         struct video_device videodev;
140         struct v4l2_device v4l2_dev;
141
142         u8 *transfer_buffer;
143         struct mutex lock;      /* buffer locking */
144         int curfreq;
145         int stereo;
146         int removed;
147         int muted;
148 };
149
150 static struct usb_device_id usb_dsbr100_device_table [] = {
151         { USB_DEVICE(DSB100_VENDOR, DSB100_PRODUCT) },
152         { }                                             /* Terminating entry */
153 };
154
155 MODULE_DEVICE_TABLE (usb, usb_dsbr100_device_table);
156
157 /* USB subsystem interface */
158 static struct usb_driver usb_dsbr100_driver = {
159         .name                   = "dsbr100",
160         .probe                  = usb_dsbr100_probe,
161         .disconnect             = usb_dsbr100_disconnect,
162         .id_table               = usb_dsbr100_device_table,
163         .suspend                = usb_dsbr100_suspend,
164         .resume                 = usb_dsbr100_resume,
165         .reset_resume           = usb_dsbr100_resume,
166         .supports_autosuspend   = 0,
167 };
168
169 /* Low-level device interface begins here */
170
171 /* switch on radio */
172 static int dsbr100_start(struct dsbr100_device *radio)
173 {
174         int retval;
175         int request;
176
177         mutex_lock(&radio->lock);
178
179         retval = usb_control_msg(radio->usbdev,
180                 usb_rcvctrlpipe(radio->usbdev, 0),
181                 USB_REQ_GET_STATUS,
182                 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
183                 0x00, 0xC7, radio->transfer_buffer, 8, 300);
184
185         if (retval < 0) {
186                 request = USB_REQ_GET_STATUS;
187                 goto usb_control_msg_failed;
188         }
189
190         retval = usb_control_msg(radio->usbdev,
191                 usb_rcvctrlpipe(radio->usbdev, 0),
192                 DSB100_ONOFF,
193                 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
194                 0x01, 0x00, radio->transfer_buffer, 8, 300);
195
196         if (retval < 0) {
197                 request = DSB100_ONOFF;
198                 goto usb_control_msg_failed;
199         }
200
201         radio->muted = 0;
202         mutex_unlock(&radio->lock);
203         return (radio->transfer_buffer)[0];
204
205 usb_control_msg_failed:
206         mutex_unlock(&radio->lock);
207         dev_err(&radio->usbdev->dev,
208                 "%s - usb_control_msg returned %i, request %i\n",
209                         __func__, retval, request);
210         return retval;
211
212 }
213
214 /* switch off radio */
215 static int dsbr100_stop(struct dsbr100_device *radio)
216 {
217         int retval;
218         int request;
219
220         mutex_lock(&radio->lock);
221
222         retval = usb_control_msg(radio->usbdev,
223                 usb_rcvctrlpipe(radio->usbdev, 0),
224                 USB_REQ_GET_STATUS,
225                 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
226                 0x16, 0x1C, radio->transfer_buffer, 8, 300);
227
228         if (retval < 0) {
229                 request = USB_REQ_GET_STATUS;
230                 goto usb_control_msg_failed;
231         }
232
233         retval = usb_control_msg(radio->usbdev,
234                 usb_rcvctrlpipe(radio->usbdev, 0),
235                 DSB100_ONOFF,
236                 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
237                 0x00, 0x00, radio->transfer_buffer, 8, 300);
238
239         if (retval < 0) {
240                 request = DSB100_ONOFF;
241                 goto usb_control_msg_failed;
242         }
243
244         radio->muted = 1;
245         mutex_unlock(&radio->lock);
246         return (radio->transfer_buffer)[0];
247
248 usb_control_msg_failed:
249         mutex_unlock(&radio->lock);
250         dev_err(&radio->usbdev->dev,
251                 "%s - usb_control_msg returned %i, request %i\n",
252                         __func__, retval, request);
253         return retval;
254
255 }
256
257 /* set a frequency, freq is defined by v4l's TUNER_LOW, i.e. 1/16th kHz */
258 static int dsbr100_setfreq(struct dsbr100_device *radio)
259 {
260         int retval;
261         int request;
262         int freq = (radio->curfreq / 16 * 80) / 1000 + 856;
263
264         mutex_lock(&radio->lock);
265
266         retval = usb_control_msg(radio->usbdev,
267                 usb_rcvctrlpipe(radio->usbdev, 0),
268                 DSB100_TUNE,
269                 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
270                 (freq >> 8) & 0x00ff, freq & 0xff,
271                 radio->transfer_buffer, 8, 300);
272
273         if (retval < 0) {
274                 request = DSB100_TUNE;
275                 goto usb_control_msg_failed;
276         }
277
278         retval = usb_control_msg(radio->usbdev,
279                 usb_rcvctrlpipe(radio->usbdev, 0),
280                 USB_REQ_GET_STATUS,
281                 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
282                 0x96, 0xB7, radio->transfer_buffer, 8, 300);
283
284         if (retval < 0) {
285                 request = USB_REQ_GET_STATUS;
286                 goto usb_control_msg_failed;
287         }
288
289         retval = usb_control_msg(radio->usbdev,
290                 usb_rcvctrlpipe(radio->usbdev, 0),
291                 USB_REQ_GET_STATUS,
292                 USB_TYPE_VENDOR | USB_RECIP_DEVICE |  USB_DIR_IN,
293                 0x00, 0x24, radio->transfer_buffer, 8, 300);
294
295         if (retval < 0) {
296                 request = USB_REQ_GET_STATUS;
297                 goto usb_control_msg_failed;
298         }
299
300         radio->stereo = !((radio->transfer_buffer)[0] & 0x01);
301         mutex_unlock(&radio->lock);
302         return (radio->transfer_buffer)[0];
303
304 usb_control_msg_failed:
305         radio->stereo = -1;
306         mutex_unlock(&radio->lock);
307         dev_err(&radio->usbdev->dev,
308                 "%s - usb_control_msg returned %i, request %i\n",
309                         __func__, retval, request);
310         return retval;
311 }
312
313 /* return the device status.  This is, in effect, just whether it
314 sees a stereo signal or not.  Pity. */
315 static void dsbr100_getstat(struct dsbr100_device *radio)
316 {
317         int retval;
318
319         mutex_lock(&radio->lock);
320
321         retval = usb_control_msg(radio->usbdev,
322                 usb_rcvctrlpipe(radio->usbdev, 0),
323                 USB_REQ_GET_STATUS,
324                 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
325                 0x00 , 0x24, radio->transfer_buffer, 8, 300);
326
327         if (retval < 0) {
328                 radio->stereo = -1;
329                 dev_err(&radio->usbdev->dev,
330                         "%s - usb_control_msg returned %i, request %i\n",
331                                 __func__, retval, USB_REQ_GET_STATUS);
332         } else {
333                 radio->stereo = !(radio->transfer_buffer[0] & 0x01);
334         }
335
336         mutex_unlock(&radio->lock);
337 }
338
339 /* USB subsystem interface begins here */
340
341 /*
342  * Handle unplugging of the device.
343  * We call video_unregister_device in any case.
344  * The last function called in this procedure is
345  * usb_dsbr100_video_device_release
346  */
347 static void usb_dsbr100_disconnect(struct usb_interface *intf)
348 {
349         struct dsbr100_device *radio = usb_get_intfdata(intf);
350
351         usb_set_intfdata (intf, NULL);
352
353         mutex_lock(&radio->lock);
354         radio->removed = 1;
355         mutex_unlock(&radio->lock);
356
357         video_unregister_device(&radio->videodev);
358         v4l2_device_disconnect(&radio->v4l2_dev);
359 }
360
361
362 static int vidioc_querycap(struct file *file, void *priv,
363                                         struct v4l2_capability *v)
364 {
365         struct dsbr100_device *radio = video_drvdata(file);
366
367         strlcpy(v->driver, "dsbr100", sizeof(v->driver));
368         strlcpy(v->card, "D-Link R-100 USB FM Radio", sizeof(v->card));
369         usb_make_path(radio->usbdev, v->bus_info, sizeof(v->bus_info));
370         v->version = RADIO_VERSION;
371         v->capabilities = V4L2_CAP_TUNER;
372         return 0;
373 }
374
375 static int vidioc_g_tuner(struct file *file, void *priv,
376                                 struct v4l2_tuner *v)
377 {
378         struct dsbr100_device *radio = video_drvdata(file);
379
380         /* safety check */
381         if (radio->removed)
382                 return -EIO;
383
384         if (v->index > 0)
385                 return -EINVAL;
386
387         dsbr100_getstat(radio);
388         strcpy(v->name, "FM");
389         v->type = V4L2_TUNER_RADIO;
390         v->rangelow = FREQ_MIN * FREQ_MUL;
391         v->rangehigh = FREQ_MAX * FREQ_MUL;
392         v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
393         v->capability = V4L2_TUNER_CAP_LOW;
394         if(radio->stereo)
395                 v->audmode = V4L2_TUNER_MODE_STEREO;
396         else
397                 v->audmode = V4L2_TUNER_MODE_MONO;
398         v->signal = 0xffff;     /* We can't get the signal strength */
399         return 0;
400 }
401
402 static int vidioc_s_tuner(struct file *file, void *priv,
403                                 struct v4l2_tuner *v)
404 {
405         struct dsbr100_device *radio = video_drvdata(file);
406
407         /* safety check */
408         if (radio->removed)
409                 return -EIO;
410
411         if (v->index > 0)
412                 return -EINVAL;
413
414         return 0;
415 }
416
417 static int vidioc_s_frequency(struct file *file, void *priv,
418                                 struct v4l2_frequency *f)
419 {
420         struct dsbr100_device *radio = video_drvdata(file);
421         int retval;
422
423         /* safety check */
424         if (radio->removed)
425                 return -EIO;
426
427         mutex_lock(&radio->lock);
428         radio->curfreq = f->frequency;
429         mutex_unlock(&radio->lock);
430
431         retval = dsbr100_setfreq(radio);
432         if (retval < 0)
433                 dev_warn(&radio->usbdev->dev, "Set frequency failed\n");
434         return 0;
435 }
436
437 static int vidioc_g_frequency(struct file *file, void *priv,
438                                 struct v4l2_frequency *f)
439 {
440         struct dsbr100_device *radio = video_drvdata(file);
441
442         /* safety check */
443         if (radio->removed)
444                 return -EIO;
445
446         f->type = V4L2_TUNER_RADIO;
447         f->frequency = radio->curfreq;
448         return 0;
449 }
450
451 static int vidioc_queryctrl(struct file *file, void *priv,
452                                 struct v4l2_queryctrl *qc)
453 {
454         switch (qc->id) {
455         case V4L2_CID_AUDIO_MUTE:
456                 return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);
457         }
458
459         return -EINVAL;
460 }
461
462 static int vidioc_g_ctrl(struct file *file, void *priv,
463                                 struct v4l2_control *ctrl)
464 {
465         struct dsbr100_device *radio = video_drvdata(file);
466
467         /* safety check */
468         if (radio->removed)
469                 return -EIO;
470
471         switch (ctrl->id) {
472         case V4L2_CID_AUDIO_MUTE:
473                 ctrl->value = radio->muted;
474                 return 0;
475         }
476         return -EINVAL;
477 }
478
479 static int vidioc_s_ctrl(struct file *file, void *priv,
480                                 struct v4l2_control *ctrl)
481 {
482         struct dsbr100_device *radio = video_drvdata(file);
483         int retval;
484
485         /* safety check */
486         if (radio->removed)
487                 return -EIO;
488
489         switch (ctrl->id) {
490         case V4L2_CID_AUDIO_MUTE:
491                 if (ctrl->value) {
492                         retval = dsbr100_stop(radio);
493                         if (retval < 0) {
494                                 dev_warn(&radio->usbdev->dev,
495                                          "Radio did not respond properly\n");
496                                 return -EBUSY;
497                         }
498                 } else {
499                         retval = dsbr100_start(radio);
500                         if (retval < 0) {
501                                 dev_warn(&radio->usbdev->dev,
502                                          "Radio did not respond properly\n");
503                                 return -EBUSY;
504                         }
505                 }
506                 return 0;
507         }
508         return -EINVAL;
509 }
510
511 static int vidioc_g_audio(struct file *file, void *priv,
512                                 struct v4l2_audio *a)
513 {
514         if (a->index > 1)
515                 return -EINVAL;
516
517         strcpy(a->name, "Radio");
518         a->capability = V4L2_AUDCAP_STEREO;
519         return 0;
520 }
521
522 static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
523 {
524         *i = 0;
525         return 0;
526 }
527
528 static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
529 {
530         if (i != 0)
531                 return -EINVAL;
532         return 0;
533 }
534
535 static int vidioc_s_audio(struct file *file, void *priv,
536                                         struct v4l2_audio *a)
537 {
538         if (a->index != 0)
539                 return -EINVAL;
540         return 0;
541 }
542
543 /* Suspend device - stop device. */
544 static int usb_dsbr100_suspend(struct usb_interface *intf, pm_message_t message)
545 {
546         struct dsbr100_device *radio = usb_get_intfdata(intf);
547         int retval;
548
549         retval = dsbr100_stop(radio);
550         if (retval < 0)
551                 dev_warn(&intf->dev, "dsbr100_stop failed\n");
552
553         dev_info(&intf->dev, "going into suspend..\n");
554
555         return 0;
556 }
557
558 /* Resume device - start device. */
559 static int usb_dsbr100_resume(struct usb_interface *intf)
560 {
561         struct dsbr100_device *radio = usb_get_intfdata(intf);
562         int retval;
563
564         retval = dsbr100_start(radio);
565         if (retval < 0)
566                 dev_warn(&intf->dev, "dsbr100_start failed\n");
567
568         dev_info(&intf->dev, "coming out of suspend..\n");
569
570         return 0;
571 }
572
573 /* free data structures */
574 static void usb_dsbr100_video_device_release(struct video_device *videodev)
575 {
576         struct dsbr100_device *radio = videodev_to_radio(videodev);
577
578         v4l2_device_unregister(&radio->v4l2_dev);
579         kfree(radio->transfer_buffer);
580         kfree(radio);
581 }
582
583 /* File system interface */
584 static const struct v4l2_file_operations usb_dsbr100_fops = {
585         .owner          = THIS_MODULE,
586         .ioctl          = video_ioctl2,
587 };
588
589 static const struct v4l2_ioctl_ops usb_dsbr100_ioctl_ops = {
590         .vidioc_querycap    = vidioc_querycap,
591         .vidioc_g_tuner     = vidioc_g_tuner,
592         .vidioc_s_tuner     = vidioc_s_tuner,
593         .vidioc_g_frequency = vidioc_g_frequency,
594         .vidioc_s_frequency = vidioc_s_frequency,
595         .vidioc_queryctrl   = vidioc_queryctrl,
596         .vidioc_g_ctrl      = vidioc_g_ctrl,
597         .vidioc_s_ctrl      = vidioc_s_ctrl,
598         .vidioc_g_audio     = vidioc_g_audio,
599         .vidioc_s_audio     = vidioc_s_audio,
600         .vidioc_g_input     = vidioc_g_input,
601         .vidioc_s_input     = vidioc_s_input,
602 };
603
604 /* check if the device is present and register with v4l and usb if it is */
605 static int usb_dsbr100_probe(struct usb_interface *intf,
606                                 const struct usb_device_id *id)
607 {
608         struct dsbr100_device *radio;
609         struct v4l2_device *v4l2_dev;
610         int retval;
611
612         radio = kzalloc(sizeof(struct dsbr100_device), GFP_KERNEL);
613
614         if (!radio)
615                 return -ENOMEM;
616
617         radio->transfer_buffer = kmalloc(TB_LEN, GFP_KERNEL);
618
619         if (!(radio->transfer_buffer)) {
620                 kfree(radio);
621                 return -ENOMEM;
622         }
623
624         v4l2_dev = &radio->v4l2_dev;
625
626         retval = v4l2_device_register(&intf->dev, v4l2_dev);
627         if (retval < 0) {
628                 v4l2_err(v4l2_dev, "couldn't register v4l2_device\n");
629                 kfree(radio->transfer_buffer);
630                 kfree(radio);
631                 return retval;
632         }
633
634         strlcpy(radio->videodev.name, v4l2_dev->name, sizeof(radio->videodev.name));
635         radio->videodev.v4l2_dev = v4l2_dev;
636         radio->videodev.fops = &usb_dsbr100_fops;
637         radio->videodev.ioctl_ops = &usb_dsbr100_ioctl_ops;
638         radio->videodev.release = usb_dsbr100_video_device_release;
639
640         mutex_init(&radio->lock);
641
642         radio->removed = 0;
643         radio->usbdev = interface_to_usbdev(intf);
644         radio->curfreq = FREQ_MIN * FREQ_MUL;
645
646         video_set_drvdata(&radio->videodev, radio);
647
648         retval = video_register_device(&radio->videodev, VFL_TYPE_RADIO, radio_nr);
649         if (retval < 0) {
650                 v4l2_err(v4l2_dev, "couldn't register video device\n");
651                 v4l2_device_unregister(v4l2_dev);
652                 kfree(radio->transfer_buffer);
653                 kfree(radio);
654                 return -EIO;
655         }
656         usb_set_intfdata(intf, radio);
657         return 0;
658 }
659
660 static int __init dsbr100_init(void)
661 {
662         int retval = usb_register(&usb_dsbr100_driver);
663         printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
664                DRIVER_DESC "\n");
665         return retval;
666 }
667
668 static void __exit dsbr100_exit(void)
669 {
670         usb_deregister(&usb_dsbr100_driver);
671 }
672
673 module_init (dsbr100_init);
674 module_exit (dsbr100_exit);
675
676 MODULE_AUTHOR( DRIVER_AUTHOR );
677 MODULE_DESCRIPTION( DRIVER_DESC );
678 MODULE_LICENSE("GPL");