V4L/DVB (10057): dsbr100: place dev_warn instead of printk
[safe/jmp/linux-2.6] / drivers / media / radio / dsbr100.c
1 /* A driver for the D-Link DSB-R100 USB radio.  The R100 plugs
2  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.43:
37         Oliver Neukum: avoided DMA coherency issue
38
39  Version 0.42:
40         Converted dsbr100 to use video_ioctl2
41         by Douglas Landgraf <dougsland@gmail.com>
42
43  Version 0.41-ac1:
44         Alan Cox: Some cleanups and fixes
45
46  Version 0.41:
47         Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org>
48
49  Version 0.40:
50         Markus: Updates for 2.6.x kernels, code layout changes, name sanitizing
51
52  Version 0.30:
53         Markus: Updates for 2.5.x kernel and more ISO compliant source
54
55  Version 0.25:
56         PSL and Markus: Cleanup, radio now doesn't stop on device close
57
58  Version 0.24:
59         Markus: Hope I got these silly VIDEO_TUNER_LOW issues finally
60         right.  Some minor cleanup, improved standalone compilation
61
62  Version 0.23:
63         Markus: Sign extension bug fixed by declaring transfer_buffer unsigned
64
65  Version 0.22:
66         Markus: Some (brown bag) cleanup in what VIDIOCSTUNER returns,
67         thanks to Mike Cox for pointing the problem out.
68
69  Version 0.21:
70         Markus: Minor cleanup, warnings if something goes wrong, lame attempt
71         to adhere to Documentation/CodingStyle
72
73  Version 0.2:
74         Brad Hards <bradh@dynamite.com.au>: Fixes to make it work as non-module
75         Markus: Copyright clarification
76
77  Version 0.01: Markus: initial release
78
79 */
80
81 #include <linux/kernel.h>
82 #include <linux/module.h>
83 #include <linux/init.h>
84 #include <linux/slab.h>
85 #include <linux/input.h>
86 #include <linux/videodev2.h>
87 #include <media/v4l2-common.h>
88 #include <media/v4l2-ioctl.h>
89 #include <linux/usb.h>
90
91 /*
92  * Version Information
93  */
94 #include <linux/version.h>      /* for KERNEL_VERSION MACRO     */
95
96 #define DRIVER_VERSION "v0.43"
97 #define RADIO_VERSION KERNEL_VERSION(0, 4, 3)
98
99 static struct v4l2_queryctrl radio_qctrl[] = {
100         {
101                 .id            = V4L2_CID_AUDIO_MUTE,
102                 .name          = "Mute",
103                 .minimum       = 0,
104                 .maximum       = 1,
105                 .default_value = 1,
106                 .type          = V4L2_CTRL_TYPE_BOOLEAN,
107         },
108 /* HINT: the disabled controls are only here to satify kradio and such apps */
109         {       .id             = V4L2_CID_AUDIO_VOLUME,
110                 .flags          = V4L2_CTRL_FLAG_DISABLED,
111         },
112         {
113                 .id             = V4L2_CID_AUDIO_BALANCE,
114                 .flags          = V4L2_CTRL_FLAG_DISABLED,
115         },
116         {
117                 .id             = V4L2_CID_AUDIO_BASS,
118                 .flags          = V4L2_CTRL_FLAG_DISABLED,
119         },
120         {
121                 .id             = V4L2_CID_AUDIO_TREBLE,
122                 .flags          = V4L2_CTRL_FLAG_DISABLED,
123         },
124         {
125                 .id             = V4L2_CID_AUDIO_LOUDNESS,
126                 .flags          = V4L2_CTRL_FLAG_DISABLED,
127         },
128 };
129
130 #define DRIVER_AUTHOR "Markus Demleitner <msdemlei@tucana.harvard.edu>"
131 #define DRIVER_DESC "D-Link DSB-R100 USB FM radio driver"
132
133 #define DSB100_VENDOR 0x04b4
134 #define DSB100_PRODUCT 0x1002
135
136 /* Commands the device appears to understand */
137 #define DSB100_TUNE 1
138 #define DSB100_ONOFF 2
139
140 #define TB_LEN 16
141
142 /* Frequency limits in MHz -- these are European values.  For Japanese
143 devices, that would be 76 and 91.  */
144 #define FREQ_MIN  87.5
145 #define FREQ_MAX 108.0
146 #define FREQ_MUL 16000
147
148 #define videodev_to_radio(d) container_of(d, struct dsbr100_device, videodev)
149
150 static int usb_dsbr100_probe(struct usb_interface *intf,
151                              const struct usb_device_id *id);
152 static void usb_dsbr100_disconnect(struct usb_interface *intf);
153 static int usb_dsbr100_open(struct inode *inode, struct file *file);
154 static int usb_dsbr100_close(struct inode *inode, struct file *file);
155 static int usb_dsbr100_suspend(struct usb_interface *intf,
156                                                 pm_message_t message);
157 static int usb_dsbr100_resume(struct usb_interface *intf);
158
159 static int radio_nr = -1;
160 module_param(radio_nr, int, 0);
161
162 /* Data for one (physical) device */
163 struct dsbr100_device {
164         struct usb_device *usbdev;
165         struct video_device videodev;
166         u8 *transfer_buffer;
167         struct mutex lock;      /* buffer locking */
168         int curfreq;
169         int stereo;
170         int users;
171         int removed;
172         int muted;
173 };
174
175
176 static struct usb_device_id usb_dsbr100_device_table [] = {
177         { USB_DEVICE(DSB100_VENDOR, DSB100_PRODUCT) },
178         { }                                             /* Terminating entry */
179 };
180
181 MODULE_DEVICE_TABLE (usb, usb_dsbr100_device_table);
182
183 /* USB subsystem interface */
184 static struct usb_driver usb_dsbr100_driver = {
185         .name                   = "dsbr100",
186         .probe                  = usb_dsbr100_probe,
187         .disconnect             = usb_dsbr100_disconnect,
188         .id_table               = usb_dsbr100_device_table,
189         .suspend                = usb_dsbr100_suspend,
190         .resume                 = usb_dsbr100_resume,
191         .reset_resume           = usb_dsbr100_resume,
192         .supports_autosuspend   = 0,
193 };
194
195 /* Low-level device interface begins here */
196
197 /* switch on radio */
198 static int dsbr100_start(struct dsbr100_device *radio)
199 {
200         mutex_lock(&radio->lock);
201         if (usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0),
202                         USB_REQ_GET_STATUS,
203                         USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
204                         0x00, 0xC7, radio->transfer_buffer, 8, 300) < 0 ||
205         usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0),
206                         DSB100_ONOFF,
207                         USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
208                         0x01, 0x00, radio->transfer_buffer, 8, 300) < 0) {
209                 mutex_unlock(&radio->lock);
210                 return -1;
211         }
212
213         radio->muted=0;
214         mutex_unlock(&radio->lock);
215         return (radio->transfer_buffer)[0];
216 }
217
218
219 /* switch off radio */
220 static int dsbr100_stop(struct dsbr100_device *radio)
221 {
222         mutex_lock(&radio->lock);
223         if (usb_control_msg(radio->usbdev, 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) < 0 ||
227         usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0),
228                         DSB100_ONOFF,
229                         USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
230                         0x00, 0x00, radio->transfer_buffer, 8, 300) < 0) {
231                 mutex_unlock(&radio->lock);
232                 return -1;
233         }
234
235         radio->muted=1;
236         mutex_unlock(&radio->lock);
237         return (radio->transfer_buffer)[0];
238 }
239
240 /* set a frequency, freq is defined by v4l's TUNER_LOW, i.e. 1/16th kHz */
241 static int dsbr100_setfreq(struct dsbr100_device *radio, int freq)
242 {
243         freq = (freq / 16 * 80) / 1000 + 856;
244         mutex_lock(&radio->lock);
245         if (usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0),
246                         DSB100_TUNE,
247                         USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
248                         (freq >> 8) & 0x00ff, freq & 0xff,
249                         radio->transfer_buffer, 8, 300) < 0 ||
250            usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0),
251                         USB_REQ_GET_STATUS,
252                         USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
253                         0x96, 0xB7, radio->transfer_buffer, 8, 300) < 0 ||
254         usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0),
255                         USB_REQ_GET_STATUS,
256                         USB_TYPE_VENDOR | USB_RECIP_DEVICE |  USB_DIR_IN,
257                         0x00, 0x24, radio->transfer_buffer, 8, 300) < 0) {
258                 radio->stereo = -1;
259                 mutex_unlock(&radio->lock);
260                 return -1;
261         }
262
263         radio->stereo = !((radio->transfer_buffer)[0] & 0x01);
264         mutex_unlock(&radio->lock);
265         return (radio->transfer_buffer)[0];
266 }
267
268 /* return the device status.  This is, in effect, just whether it
269 sees a stereo signal or not.  Pity. */
270 static void dsbr100_getstat(struct dsbr100_device *radio)
271 {
272         mutex_lock(&radio->lock);
273         if (usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0),
274                 USB_REQ_GET_STATUS,
275                 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
276                 0x00 , 0x24, radio->transfer_buffer, 8, 300) < 0)
277                 radio->stereo = -1;
278         else
279                 radio->stereo = !(radio->transfer_buffer[0] & 0x01);
280         mutex_unlock(&radio->lock);
281 }
282
283
284 /* USB subsystem interface begins here */
285
286 /* handle unplugging of the device, release data structures
287 if nothing keeps us from doing it.  If something is still
288 keeping us busy, the release callback of v4l will take care
289 of releasing it. */
290 static void usb_dsbr100_disconnect(struct usb_interface *intf)
291 {
292         struct dsbr100_device *radio = usb_get_intfdata(intf);
293
294         usb_set_intfdata (intf, NULL);
295
296         mutex_lock(&radio->lock);
297         radio->removed = 1;
298         mutex_unlock(&radio->lock);
299
300         video_unregister_device(&radio->videodev);
301 }
302
303
304 static int vidioc_querycap(struct file *file, void *priv,
305                                         struct v4l2_capability *v)
306 {
307         strlcpy(v->driver, "dsbr100", sizeof(v->driver));
308         strlcpy(v->card, "D-Link R-100 USB FM Radio", sizeof(v->card));
309         sprintf(v->bus_info, "USB");
310         v->version = RADIO_VERSION;
311         v->capabilities = V4L2_CAP_TUNER;
312         return 0;
313 }
314
315 static int vidioc_g_tuner(struct file *file, void *priv,
316                                 struct v4l2_tuner *v)
317 {
318         struct dsbr100_device *radio = video_drvdata(file);
319
320         /* safety check */
321         if (radio->removed)
322                 return -EIO;
323
324         if (v->index > 0)
325                 return -EINVAL;
326
327         dsbr100_getstat(radio);
328         strcpy(v->name, "FM");
329         v->type = V4L2_TUNER_RADIO;
330         v->rangelow = FREQ_MIN * FREQ_MUL;
331         v->rangehigh = FREQ_MAX * FREQ_MUL;
332         v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
333         v->capability = V4L2_TUNER_CAP_LOW;
334         if(radio->stereo)
335                 v->audmode = V4L2_TUNER_MODE_STEREO;
336         else
337                 v->audmode = V4L2_TUNER_MODE_MONO;
338         v->signal = 0xffff;     /* We can't get the signal strength */
339         return 0;
340 }
341
342 static int vidioc_s_tuner(struct file *file, void *priv,
343                                 struct v4l2_tuner *v)
344 {
345         struct dsbr100_device *radio = video_drvdata(file);
346
347         /* safety check */
348         if (radio->removed)
349                 return -EIO;
350
351         if (v->index > 0)
352                 return -EINVAL;
353
354         return 0;
355 }
356
357 static int vidioc_s_frequency(struct file *file, void *priv,
358                                 struct v4l2_frequency *f)
359 {
360         struct dsbr100_device *radio = video_drvdata(file);
361
362         /* safety check */
363         if (radio->removed)
364                 return -EIO;
365
366         radio->curfreq = f->frequency;
367         if (dsbr100_setfreq(radio, radio->curfreq) == -1)
368                 dev_warn(&radio->usbdev->dev, "Set frequency failed\n");
369         return 0;
370 }
371
372 static int vidioc_g_frequency(struct file *file, void *priv,
373                                 struct v4l2_frequency *f)
374 {
375         struct dsbr100_device *radio = video_drvdata(file);
376
377         /* safety check */
378         if (radio->removed)
379                 return -EIO;
380
381         f->type = V4L2_TUNER_RADIO;
382         f->frequency = radio->curfreq;
383         return 0;
384 }
385
386 static int vidioc_queryctrl(struct file *file, void *priv,
387                                 struct v4l2_queryctrl *qc)
388 {
389         int i;
390
391         for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
392                 if (qc->id && qc->id == radio_qctrl[i].id) {
393                         memcpy(qc, &(radio_qctrl[i]), sizeof(*qc));
394                         return 0;
395                 }
396         }
397         return -EINVAL;
398 }
399
400 static int vidioc_g_ctrl(struct file *file, void *priv,
401                                 struct v4l2_control *ctrl)
402 {
403         struct dsbr100_device *radio = video_drvdata(file);
404
405         /* safety check */
406         if (radio->removed)
407                 return -EIO;
408
409         switch (ctrl->id) {
410         case V4L2_CID_AUDIO_MUTE:
411                 ctrl->value = radio->muted;
412                 return 0;
413         }
414         return -EINVAL;
415 }
416
417 static int vidioc_s_ctrl(struct file *file, void *priv,
418                                 struct v4l2_control *ctrl)
419 {
420         struct dsbr100_device *radio = video_drvdata(file);
421
422         /* safety check */
423         if (radio->removed)
424                 return -EIO;
425
426         switch (ctrl->id) {
427         case V4L2_CID_AUDIO_MUTE:
428                 if (ctrl->value) {
429                         if (dsbr100_stop(radio) == -1) {
430                                 dev_warn(&radio->usbdev->dev,
431                                          "Radio did not respond properly\n");
432                                 return -EBUSY;
433                         }
434                 } else {
435                         if (dsbr100_start(radio) == -1) {
436                                 dev_warn(&radio->usbdev->dev,
437                                          "Radio did not respond properly\n");
438                                 return -EBUSY;
439                         }
440                 }
441                 return 0;
442         }
443         return -EINVAL;
444 }
445
446 static int vidioc_g_audio(struct file *file, void *priv,
447                                 struct v4l2_audio *a)
448 {
449         if (a->index > 1)
450                 return -EINVAL;
451
452         strcpy(a->name, "Radio");
453         a->capability = V4L2_AUDCAP_STEREO;
454         return 0;
455 }
456
457 static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
458 {
459         *i = 0;
460         return 0;
461 }
462
463 static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
464 {
465         if (i != 0)
466                 return -EINVAL;
467         return 0;
468 }
469
470 static int vidioc_s_audio(struct file *file, void *priv,
471                                         struct v4l2_audio *a)
472 {
473         if (a->index != 0)
474                 return -EINVAL;
475         return 0;
476 }
477
478 static int usb_dsbr100_open(struct inode *inode, struct file *file)
479 {
480         struct dsbr100_device *radio = video_drvdata(file);
481         int retval;
482
483         lock_kernel();
484         radio->users = 1;
485         radio->muted = 1;
486
487         if (dsbr100_start(radio) < 0) {
488                 dev_warn(&radio->usbdev->dev,
489                          "Radio did not start up properly\n");
490                 radio->users = 0;
491                 unlock_kernel();
492                 return -EIO;
493         }
494
495         retval = dsbr100_setfreq(radio, radio->curfreq);
496
497         if (retval == -1)
498                 dev_warn(&radio->usbdev->dev,
499                         "set frequency failed\n");
500
501         unlock_kernel();
502         return 0;
503 }
504
505 static int usb_dsbr100_close(struct inode *inode, struct file *file)
506 {
507         struct dsbr100_device *radio = video_drvdata(file);
508         int retval;
509
510         if (!radio)
511                 return -ENODEV;
512
513         radio->users = 0;
514         if (!radio->removed) {
515                 retval = dsbr100_stop(radio);
516                 if (retval == -1) {
517                         dev_warn(&radio->usbdev->dev,
518                                 "dsbr100_stop failed\n");
519                 }
520
521         }
522         return 0;
523 }
524
525 /* Suspend device - stop device. */
526 static int usb_dsbr100_suspend(struct usb_interface *intf, pm_message_t message)
527 {
528         struct dsbr100_device *radio = usb_get_intfdata(intf);
529         int retval;
530
531         retval = dsbr100_stop(radio);
532         if (retval == -1)
533                 dev_warn(&intf->dev, "dsbr100_stop failed\n");
534
535         dev_info(&intf->dev, "going into suspend..\n");
536
537         return 0;
538 }
539
540 /* Resume device - start device. */
541 static int usb_dsbr100_resume(struct usb_interface *intf)
542 {
543         struct dsbr100_device *radio = usb_get_intfdata(intf);
544         int retval;
545
546         retval = dsbr100_start(radio);
547         if (retval == -1)
548                 dev_warn(&intf->dev, "dsbr100_start failed\n");
549
550         dev_info(&intf->dev, "coming out of suspend..\n");
551
552         return 0;
553 }
554
555 static void usb_dsbr100_video_device_release(struct video_device *videodev)
556 {
557         struct dsbr100_device *radio = videodev_to_radio(videodev);
558
559         kfree(radio->transfer_buffer);
560         kfree(radio);
561 }
562
563 /* File system interface */
564 static const struct file_operations usb_dsbr100_fops = {
565         .owner          = THIS_MODULE,
566         .open           = usb_dsbr100_open,
567         .release        = usb_dsbr100_close,
568         .ioctl          = video_ioctl2,
569 #ifdef CONFIG_COMPAT
570         .compat_ioctl   = v4l_compat_ioctl32,
571 #endif
572         .llseek         = no_llseek,
573 };
574
575 static const struct v4l2_ioctl_ops usb_dsbr100_ioctl_ops = {
576         .vidioc_querycap    = vidioc_querycap,
577         .vidioc_g_tuner     = vidioc_g_tuner,
578         .vidioc_s_tuner     = vidioc_s_tuner,
579         .vidioc_g_frequency = vidioc_g_frequency,
580         .vidioc_s_frequency = vidioc_s_frequency,
581         .vidioc_queryctrl   = vidioc_queryctrl,
582         .vidioc_g_ctrl      = vidioc_g_ctrl,
583         .vidioc_s_ctrl      = vidioc_s_ctrl,
584         .vidioc_g_audio     = vidioc_g_audio,
585         .vidioc_s_audio     = vidioc_s_audio,
586         .vidioc_g_input     = vidioc_g_input,
587         .vidioc_s_input     = vidioc_s_input,
588 };
589
590 /* V4L2 interface */
591 static struct video_device dsbr100_videodev_data = {
592         .name           = "D-Link DSB-R 100",
593         .fops           = &usb_dsbr100_fops,
594         .ioctl_ops      = &usb_dsbr100_ioctl_ops,
595         .release        = usb_dsbr100_video_device_release,
596 };
597
598 /* check if the device is present and register with v4l and
599 usb if it is */
600 static int usb_dsbr100_probe(struct usb_interface *intf,
601                                 const struct usb_device_id *id)
602 {
603         struct dsbr100_device *radio;
604
605         radio = kmalloc(sizeof(struct dsbr100_device), GFP_KERNEL);
606
607         if (!radio)
608                 return -ENOMEM;
609
610         radio->transfer_buffer = kmalloc(TB_LEN, GFP_KERNEL);
611
612         if (!(radio->transfer_buffer)) {
613                 kfree(radio);
614                 return -ENOMEM;
615         }
616
617         mutex_init(&radio->lock);
618         radio->videodev = dsbr100_videodev_data;
619
620         radio->removed = 0;
621         radio->users = 0;
622         radio->usbdev = interface_to_usbdev(intf);
623         radio->curfreq = FREQ_MIN * FREQ_MUL;
624         video_set_drvdata(&radio->videodev, radio);
625         if (video_register_device(&radio->videodev, VFL_TYPE_RADIO, radio_nr) < 0) {
626                 dev_warn(&intf->dev, "Could not register video device\n");
627                 kfree(radio->transfer_buffer);
628                 kfree(radio);
629                 return -EIO;
630         }
631         usb_set_intfdata(intf, radio);
632         return 0;
633 }
634
635 static int __init dsbr100_init(void)
636 {
637         int retval = usb_register(&usb_dsbr100_driver);
638         printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
639                DRIVER_DESC "\n");
640         return retval;
641 }
642
643 static void __exit dsbr100_exit(void)
644 {
645         usb_deregister(&usb_dsbr100_driver);
646 }
647
648 module_init (dsbr100_init);
649 module_exit (dsbr100_exit);
650
651 MODULE_AUTHOR( DRIVER_AUTHOR );
652 MODULE_DESCRIPTION( DRIVER_DESC );
653 MODULE_LICENSE("GPL");