aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/radio
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/radio')
-rw-r--r--drivers/media/radio/Kconfig12
-rw-r--r--drivers/media/radio/Makefile1
-rw-r--r--drivers/media/radio/dsbr100.c28
-rw-r--r--drivers/media/radio/radio-aimslab.c34
-rw-r--r--drivers/media/radio/radio-aztech.c40
-rw-r--r--drivers/media/radio/radio-cadet.c1
-rw-r--r--drivers/media/radio/radio-gemtek-pci.c42
-rw-r--r--drivers/media/radio/radio-gemtek.c37
-rw-r--r--drivers/media/radio/radio-maestro.c34
-rw-r--r--drivers/media/radio/radio-maxiradio.c40
-rw-r--r--drivers/media/radio/radio-mr800.c628
-rw-r--r--drivers/media/radio/radio-rtrack2.c34
-rw-r--r--drivers/media/radio/radio-sf16fmi.c34
-rw-r--r--drivers/media/radio/radio-sf16fmr2.c34
-rw-r--r--drivers/media/radio/radio-si470x.c24
-rw-r--r--drivers/media/radio/radio-terratec.c34
-rw-r--r--drivers/media/radio/radio-trust.c17
-rw-r--r--drivers/media/radio/radio-typhoon.c35
-rw-r--r--drivers/media/radio/radio-zoltrix.c51
19 files changed, 965 insertions, 195 deletions
diff --git a/drivers/media/radio/Kconfig b/drivers/media/radio/Kconfig
index 1b41b3f77cf9..e51d707e58d3 100644
--- a/drivers/media/radio/Kconfig
+++ b/drivers/media/radio/Kconfig
@@ -361,4 +361,16 @@ config USB_SI470X
361 To compile this driver as a module, choose M here: the 361 To compile this driver as a module, choose M here: the
362 module will be called radio-silabs. 362 module will be called radio-silabs.
363 363
364config USB_MR800
365 tristate "AverMedia MR 800 USB FM radio support"
366 depends on USB && VIDEO_V4L2
367 ---help---
368 Say Y here if you want to connect this type of radio to your
369 computer's USB port. Note that the audio is not digital, and
370 you must connect the line out connector to a sound card or a
371 set of speakers.
372
373 To compile this driver as a module, choose M here: the
374 module will be called radio-mr800.
375
364endif # RADIO_ADAPTERS 376endif # RADIO_ADAPTERS
diff --git a/drivers/media/radio/Makefile b/drivers/media/radio/Makefile
index 7ca71ab96b43..240ec63cdafc 100644
--- a/drivers/media/radio/Makefile
+++ b/drivers/media/radio/Makefile
@@ -18,5 +18,6 @@ obj-$(CONFIG_RADIO_TRUST) += radio-trust.o
18obj-$(CONFIG_RADIO_MAESTRO) += radio-maestro.o 18obj-$(CONFIG_RADIO_MAESTRO) += radio-maestro.o
19obj-$(CONFIG_USB_DSBR) += dsbr100.o 19obj-$(CONFIG_USB_DSBR) += dsbr100.o
20obj-$(CONFIG_USB_SI470X) += radio-si470x.o 20obj-$(CONFIG_USB_SI470X) += radio-si470x.o
21obj-$(CONFIG_USB_MR800) += radio-mr800.o
21 22
22EXTRA_CFLAGS += -Isound 23EXTRA_CFLAGS += -Isound
diff --git a/drivers/media/radio/dsbr100.c b/drivers/media/radio/dsbr100.c
index 70c65a745923..66783fffe4c1 100644
--- a/drivers/media/radio/dsbr100.c
+++ b/drivers/media/radio/dsbr100.c
@@ -274,7 +274,7 @@ static int vidioc_querycap(struct file *file, void *priv,
274static int vidioc_g_tuner(struct file *file, void *priv, 274static int vidioc_g_tuner(struct file *file, void *priv,
275 struct v4l2_tuner *v) 275 struct v4l2_tuner *v)
276{ 276{
277 struct dsbr100_device *radio = video_get_drvdata(video_devdata(file)); 277 struct dsbr100_device *radio = video_drvdata(file);
278 278
279 if (v->index > 0) 279 if (v->index > 0)
280 return -EINVAL; 280 return -EINVAL;
@@ -306,7 +306,7 @@ static int vidioc_s_tuner(struct file *file, void *priv,
306static int vidioc_s_frequency(struct file *file, void *priv, 306static int vidioc_s_frequency(struct file *file, void *priv,
307 struct v4l2_frequency *f) 307 struct v4l2_frequency *f)
308{ 308{
309 struct dsbr100_device *radio = video_get_drvdata(video_devdata(file)); 309 struct dsbr100_device *radio = video_drvdata(file);
310 310
311 radio->curfreq = f->frequency; 311 radio->curfreq = f->frequency;
312 if (dsbr100_setfreq(radio, radio->curfreq)==-1) 312 if (dsbr100_setfreq(radio, radio->curfreq)==-1)
@@ -317,7 +317,7 @@ static int vidioc_s_frequency(struct file *file, void *priv,
317static int vidioc_g_frequency(struct file *file, void *priv, 317static int vidioc_g_frequency(struct file *file, void *priv,
318 struct v4l2_frequency *f) 318 struct v4l2_frequency *f)
319{ 319{
320 struct dsbr100_device *radio = video_get_drvdata(video_devdata(file)); 320 struct dsbr100_device *radio = video_drvdata(file);
321 321
322 f->type = V4L2_TUNER_RADIO; 322 f->type = V4L2_TUNER_RADIO;
323 f->frequency = radio->curfreq; 323 f->frequency = radio->curfreq;
@@ -342,7 +342,7 @@ static int vidioc_queryctrl(struct file *file, void *priv,
342static int vidioc_g_ctrl(struct file *file, void *priv, 342static int vidioc_g_ctrl(struct file *file, void *priv,
343 struct v4l2_control *ctrl) 343 struct v4l2_control *ctrl)
344{ 344{
345 struct dsbr100_device *radio = video_get_drvdata(video_devdata(file)); 345 struct dsbr100_device *radio = video_drvdata(file);
346 346
347 switch (ctrl->id) { 347 switch (ctrl->id) {
348 case V4L2_CID_AUDIO_MUTE: 348 case V4L2_CID_AUDIO_MUTE:
@@ -355,16 +355,20 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
355static int vidioc_s_ctrl(struct file *file, void *priv, 355static int vidioc_s_ctrl(struct file *file, void *priv,
356 struct v4l2_control *ctrl) 356 struct v4l2_control *ctrl)
357{ 357{
358 struct dsbr100_device *radio = video_get_drvdata(video_devdata(file)); 358 struct dsbr100_device *radio = video_drvdata(file);
359 359
360 switch (ctrl->id) { 360 switch (ctrl->id) {
361 case V4L2_CID_AUDIO_MUTE: 361 case V4L2_CID_AUDIO_MUTE:
362 if (ctrl->value) { 362 if (ctrl->value) {
363 if (dsbr100_stop(radio)==-1) 363 if (dsbr100_stop(radio) == -1) {
364 warn("Radio did not respond properly"); 364 warn("Radio did not respond properly");
365 return -EBUSY;
366 }
365 } else { 367 } else {
366 if (dsbr100_start(radio)==-1) 368 if (dsbr100_start(radio) == -1) {
367 warn("Radio did not respond properly"); 369 warn("Radio did not respond properly");
370 return -EBUSY;
371 }
368 } 372 }
369 return 0; 373 return 0;
370 } 374 }
@@ -405,23 +409,26 @@ static int vidioc_s_audio(struct file *file, void *priv,
405 409
406static int usb_dsbr100_open(struct inode *inode, struct file *file) 410static int usb_dsbr100_open(struct inode *inode, struct file *file)
407{ 411{
408 struct dsbr100_device *radio=video_get_drvdata(video_devdata(file)); 412 struct dsbr100_device *radio = video_drvdata(file);
409 413
414 lock_kernel();
410 radio->users = 1; 415 radio->users = 1;
411 radio->muted = 1; 416 radio->muted = 1;
412 417
413 if (dsbr100_start(radio)<0) { 418 if (dsbr100_start(radio)<0) {
414 warn("Radio did not start up properly"); 419 warn("Radio did not start up properly");
415 radio->users = 0; 420 radio->users = 0;
421 unlock_kernel();
416 return -EIO; 422 return -EIO;
417 } 423 }
418 dsbr100_setfreq(radio, radio->curfreq); 424 dsbr100_setfreq(radio, radio->curfreq);
425 unlock_kernel();
419 return 0; 426 return 0;
420} 427}
421 428
422static int usb_dsbr100_close(struct inode *inode, struct file *file) 429static int usb_dsbr100_close(struct inode *inode, struct file *file)
423{ 430{
424 struct dsbr100_device *radio=video_get_drvdata(video_devdata(file)); 431 struct dsbr100_device *radio = video_drvdata(file);
425 432
426 if (!radio) 433 if (!radio)
427 return -ENODEV; 434 return -ENODEV;
@@ -507,7 +514,8 @@ static int usb_dsbr100_probe(struct usb_interface *intf,
507static int __init dsbr100_init(void) 514static int __init dsbr100_init(void)
508{ 515{
509 int retval = usb_register(&usb_dsbr100_driver); 516 int retval = usb_register(&usb_dsbr100_driver);
510 info(DRIVER_VERSION ":" DRIVER_DESC); 517 printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
518 DRIVER_DESC "\n");
511 return retval; 519 return retval;
512} 520}
513 521
diff --git a/drivers/media/radio/radio-aimslab.c b/drivers/media/radio/radio-aimslab.c
index 1f064f4b32df..9305e958fc66 100644
--- a/drivers/media/radio/radio-aimslab.c
+++ b/drivers/media/radio/radio-aimslab.c
@@ -51,6 +51,7 @@ static struct mutex lock;
51 51
52struct rt_device 52struct rt_device
53{ 53{
54 unsigned long in_use;
54 int port; 55 int port;
55 int curvol; 56 int curvol;
56 unsigned long curfreq; 57 unsigned long curfreq;
@@ -245,8 +246,7 @@ static int vidioc_querycap(struct file *file, void *priv,
245static int vidioc_g_tuner(struct file *file, void *priv, 246static int vidioc_g_tuner(struct file *file, void *priv,
246 struct v4l2_tuner *v) 247 struct v4l2_tuner *v)
247{ 248{
248 struct video_device *dev = video_devdata(file); 249 struct rt_device *rt = video_drvdata(file);
249 struct rt_device *rt = dev->priv;
250 250
251 if (v->index > 0) 251 if (v->index > 0)
252 return -EINVAL; 252 return -EINVAL;
@@ -273,8 +273,7 @@ static int vidioc_s_tuner(struct file *file, void *priv,
273static int vidioc_s_frequency(struct file *file, void *priv, 273static int vidioc_s_frequency(struct file *file, void *priv,
274 struct v4l2_frequency *f) 274 struct v4l2_frequency *f)
275{ 275{
276 struct video_device *dev = video_devdata(file); 276 struct rt_device *rt = video_drvdata(file);
277 struct rt_device *rt = dev->priv;
278 277
279 rt->curfreq = f->frequency; 278 rt->curfreq = f->frequency;
280 rt_setfreq(rt, rt->curfreq); 279 rt_setfreq(rt, rt->curfreq);
@@ -284,8 +283,7 @@ static int vidioc_s_frequency(struct file *file, void *priv,
284static int vidioc_g_frequency(struct file *file, void *priv, 283static int vidioc_g_frequency(struct file *file, void *priv,
285 struct v4l2_frequency *f) 284 struct v4l2_frequency *f)
286{ 285{
287 struct video_device *dev = video_devdata(file); 286 struct rt_device *rt = video_drvdata(file);
288 struct rt_device *rt = dev->priv;
289 287
290 f->type = V4L2_TUNER_RADIO; 288 f->type = V4L2_TUNER_RADIO;
291 f->frequency = rt->curfreq; 289 f->frequency = rt->curfreq;
@@ -310,8 +308,7 @@ static int vidioc_queryctrl(struct file *file, void *priv,
310static int vidioc_g_ctrl(struct file *file, void *priv, 308static int vidioc_g_ctrl(struct file *file, void *priv,
311 struct v4l2_control *ctrl) 309 struct v4l2_control *ctrl)
312{ 310{
313 struct video_device *dev = video_devdata(file); 311 struct rt_device *rt = video_drvdata(file);
314 struct rt_device *rt = dev->priv;
315 312
316 switch (ctrl->id) { 313 switch (ctrl->id) {
317 case V4L2_CID_AUDIO_MUTE: 314 case V4L2_CID_AUDIO_MUTE:
@@ -327,8 +324,7 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
327static int vidioc_s_ctrl(struct file *file, void *priv, 324static int vidioc_s_ctrl(struct file *file, void *priv,
328 struct v4l2_control *ctrl) 325 struct v4l2_control *ctrl)
329{ 326{
330 struct video_device *dev = video_devdata(file); 327 struct rt_device *rt = video_drvdata(file);
331 struct rt_device *rt = dev->priv;
332 328
333 switch (ctrl->id) { 329 switch (ctrl->id) {
334 case V4L2_CID_AUDIO_MUTE: 330 case V4L2_CID_AUDIO_MUTE:
@@ -378,10 +374,21 @@ static int vidioc_s_audio(struct file *file, void *priv,
378 374
379static struct rt_device rtrack_unit; 375static struct rt_device rtrack_unit;
380 376
377static int rtrack_exclusive_open(struct inode *inode, struct file *file)
378{
379 return test_and_set_bit(0, &rtrack_unit.in_use) ? -EBUSY : 0;
380}
381
382static int rtrack_exclusive_release(struct inode *inode, struct file *file)
383{
384 clear_bit(0, &rtrack_unit.in_use);
385 return 0;
386}
387
381static const struct file_operations rtrack_fops = { 388static const struct file_operations rtrack_fops = {
382 .owner = THIS_MODULE, 389 .owner = THIS_MODULE,
383 .open = video_exclusive_open, 390 .open = rtrack_exclusive_open,
384 .release = video_exclusive_release, 391 .release = rtrack_exclusive_release,
385 .ioctl = video_ioctl2, 392 .ioctl = video_ioctl2,
386#ifdef CONFIG_COMPAT 393#ifdef CONFIG_COMPAT
387 .compat_ioctl = v4l_compat_ioctl32, 394 .compat_ioctl = v4l_compat_ioctl32,
@@ -408,6 +415,7 @@ static struct video_device rtrack_radio = {
408 .name = "RadioTrack radio", 415 .name = "RadioTrack radio",
409 .fops = &rtrack_fops, 416 .fops = &rtrack_fops,
410 .ioctl_ops = &rtrack_ioctl_ops, 417 .ioctl_ops = &rtrack_ioctl_ops,
418 .release = video_device_release_empty,
411}; 419};
412 420
413static int __init rtrack_init(void) 421static int __init rtrack_init(void)
@@ -424,7 +432,7 @@ static int __init rtrack_init(void)
424 return -EBUSY; 432 return -EBUSY;
425 } 433 }
426 434
427 rtrack_radio.priv=&rtrack_unit; 435 video_set_drvdata(&rtrack_radio, &rtrack_unit);
428 436
429 if (video_register_device(&rtrack_radio, VFL_TYPE_RADIO, radio_nr) < 0) { 437 if (video_register_device(&rtrack_radio, VFL_TYPE_RADIO, radio_nr) < 0) {
430 release_region(io, 2); 438 release_region(io, 2);
diff --git a/drivers/media/radio/radio-aztech.c b/drivers/media/radio/radio-aztech.c
index 628c689e3ffe..d78489573230 100644
--- a/drivers/media/radio/radio-aztech.c
+++ b/drivers/media/radio/radio-aztech.c
@@ -70,6 +70,7 @@ static struct mutex lock;
70 70
71struct az_device 71struct az_device
72{ 72{
73 unsigned long in_use;
73 int curvol; 74 int curvol;
74 unsigned long curfreq; 75 unsigned long curfreq;
75 int stereo; 76 int stereo;
@@ -195,8 +196,7 @@ static int vidioc_querycap (struct file *file, void *priv,
195static int vidioc_g_tuner (struct file *file, void *priv, 196static int vidioc_g_tuner (struct file *file, void *priv,
196 struct v4l2_tuner *v) 197 struct v4l2_tuner *v)
197{ 198{
198 struct video_device *dev = video_devdata(file); 199 struct az_device *az = video_drvdata(file);
199 struct az_device *az = dev->priv;
200 200
201 if (v->index > 0) 201 if (v->index > 0)
202 return -EINVAL; 202 return -EINVAL;
@@ -264,8 +264,7 @@ static int vidioc_s_audio (struct file *file, void *priv,
264static int vidioc_s_frequency (struct file *file, void *priv, 264static int vidioc_s_frequency (struct file *file, void *priv,
265 struct v4l2_frequency *f) 265 struct v4l2_frequency *f)
266{ 266{
267 struct video_device *dev = video_devdata(file); 267 struct az_device *az = video_drvdata(file);
268 struct az_device *az = dev->priv;
269 268
270 az->curfreq = f->frequency; 269 az->curfreq = f->frequency;
271 az_setfreq(az, az->curfreq); 270 az_setfreq(az, az->curfreq);
@@ -275,8 +274,7 @@ static int vidioc_s_frequency (struct file *file, void *priv,
275static int vidioc_g_frequency (struct file *file, void *priv, 274static int vidioc_g_frequency (struct file *file, void *priv,
276 struct v4l2_frequency *f) 275 struct v4l2_frequency *f)
277{ 276{
278 struct video_device *dev = video_devdata(file); 277 struct az_device *az = video_drvdata(file);
279 struct az_device *az = dev->priv;
280 278
281 f->type = V4L2_TUNER_RADIO; 279 f->type = V4L2_TUNER_RADIO;
282 f->frequency = az->curfreq; 280 f->frequency = az->curfreq;
@@ -302,8 +300,7 @@ static int vidioc_queryctrl (struct file *file, void *priv,
302static int vidioc_g_ctrl (struct file *file, void *priv, 300static int vidioc_g_ctrl (struct file *file, void *priv,
303 struct v4l2_control *ctrl) 301 struct v4l2_control *ctrl)
304{ 302{
305 struct video_device *dev = video_devdata(file); 303 struct az_device *az = video_drvdata(file);
306 struct az_device *az = dev->priv;
307 304
308 switch (ctrl->id) { 305 switch (ctrl->id) {
309 case V4L2_CID_AUDIO_MUTE: 306 case V4L2_CID_AUDIO_MUTE:
@@ -322,8 +319,7 @@ static int vidioc_g_ctrl (struct file *file, void *priv,
322static int vidioc_s_ctrl (struct file *file, void *priv, 319static int vidioc_s_ctrl (struct file *file, void *priv,
323 struct v4l2_control *ctrl) 320 struct v4l2_control *ctrl)
324{ 321{
325 struct video_device *dev = video_devdata(file); 322 struct az_device *az = video_drvdata(file);
326 struct az_device *az = dev->priv;
327 323
328 switch (ctrl->id) { 324 switch (ctrl->id) {
329 case V4L2_CID_AUDIO_MUTE: 325 case V4L2_CID_AUDIO_MUTE:
@@ -342,10 +338,21 @@ static int vidioc_s_ctrl (struct file *file, void *priv,
342 338
343static struct az_device aztech_unit; 339static struct az_device aztech_unit;
344 340
341static int aztech_exclusive_open(struct inode *inode, struct file *file)
342{
343 return test_and_set_bit(0, &aztech_unit.in_use) ? -EBUSY : 0;
344}
345
346static int aztech_exclusive_release(struct inode *inode, struct file *file)
347{
348 clear_bit(0, &aztech_unit.in_use);
349 return 0;
350}
351
345static const struct file_operations aztech_fops = { 352static const struct file_operations aztech_fops = {
346 .owner = THIS_MODULE, 353 .owner = THIS_MODULE,
347 .open = video_exclusive_open, 354 .open = aztech_exclusive_open,
348 .release = video_exclusive_release, 355 .release = aztech_exclusive_release,
349 .ioctl = video_ioctl2, 356 .ioctl = video_ioctl2,
350#ifdef CONFIG_COMPAT 357#ifdef CONFIG_COMPAT
351 .compat_ioctl = v4l_compat_ioctl32, 358 .compat_ioctl = v4l_compat_ioctl32,
@@ -369,9 +376,10 @@ static const struct v4l2_ioctl_ops aztech_ioctl_ops = {
369}; 376};
370 377
371static struct video_device aztech_radio = { 378static struct video_device aztech_radio = {
372 .name = "Aztech radio", 379 .name = "Aztech radio",
373 .fops = &aztech_fops, 380 .fops = &aztech_fops,
374 .ioctl_ops = &aztech_ioctl_ops, 381 .ioctl_ops = &aztech_ioctl_ops,
382 .release = video_device_release_empty,
375}; 383};
376 384
377module_param_named(debug,aztech_radio.debug, int, 0644); 385module_param_named(debug,aztech_radio.debug, int, 0644);
@@ -392,7 +400,7 @@ static int __init aztech_init(void)
392 } 400 }
393 401
394 mutex_init(&lock); 402 mutex_init(&lock);
395 aztech_radio.priv=&aztech_unit; 403 video_set_drvdata(&aztech_radio, &aztech_unit);
396 404
397 if (video_register_device(&aztech_radio, VFL_TYPE_RADIO, radio_nr) < 0) { 405 if (video_register_device(&aztech_radio, VFL_TYPE_RADIO, radio_nr) < 0) {
398 release_region(io,2); 406 release_region(io,2);
diff --git a/drivers/media/radio/radio-cadet.c b/drivers/media/radio/radio-cadet.c
index 04c3698d32e4..0490a1fa999d 100644
--- a/drivers/media/radio/radio-cadet.c
+++ b/drivers/media/radio/radio-cadet.c
@@ -589,6 +589,7 @@ static struct video_device cadet_radio = {
589 .name = "Cadet radio", 589 .name = "Cadet radio",
590 .fops = &cadet_fops, 590 .fops = &cadet_fops,
591 .ioctl_ops = &cadet_ioctl_ops, 591 .ioctl_ops = &cadet_ioctl_ops,
592 .release = video_device_release_empty,
592}; 593};
593 594
594#ifdef CONFIG_PNP 595#ifdef CONFIG_PNP
diff --git a/drivers/media/radio/radio-gemtek-pci.c b/drivers/media/radio/radio-gemtek-pci.c
index 5cd7f032298d..e15bee6d7cfc 100644
--- a/drivers/media/radio/radio-gemtek-pci.c
+++ b/drivers/media/radio/radio-gemtek-pci.c
@@ -100,9 +100,8 @@ struct gemtek_pci_card {
100 u8 mute; 100 u8 mute;
101}; 101};
102 102
103static const char rcsid[] = "$Id: radio-gemtek-pci.c,v 1.1 2001/07/23 08:08:16 ted Exp ted $";
104
105static int nr_radio = -1; 103static int nr_radio = -1;
104static unsigned long in_use;
106 105
107static inline u8 gemtek_pci_out( u16 value, u32 port ) 106static inline u8 gemtek_pci_out( u16 value, u32 port )
108{ 107{
@@ -205,8 +204,7 @@ static int vidioc_querycap(struct file *file, void *priv,
205static int vidioc_g_tuner(struct file *file, void *priv, 204static int vidioc_g_tuner(struct file *file, void *priv,
206 struct v4l2_tuner *v) 205 struct v4l2_tuner *v)
207{ 206{
208 struct video_device *dev = video_devdata(file); 207 struct gemtek_pci_card *card = video_drvdata(file);
209 struct gemtek_pci_card *card = dev->priv;
210 208
211 if (v->index > 0) 209 if (v->index > 0)
212 return -EINVAL; 210 return -EINVAL;
@@ -233,8 +231,7 @@ static int vidioc_s_tuner(struct file *file, void *priv,
233static int vidioc_s_frequency(struct file *file, void *priv, 231static int vidioc_s_frequency(struct file *file, void *priv,
234 struct v4l2_frequency *f) 232 struct v4l2_frequency *f)
235{ 233{
236 struct video_device *dev = video_devdata(file); 234 struct gemtek_pci_card *card = video_drvdata(file);
237 struct gemtek_pci_card *card = dev->priv;
238 235
239 if ( (f->frequency < GEMTEK_PCI_RANGE_LOW) || 236 if ( (f->frequency < GEMTEK_PCI_RANGE_LOW) ||
240 (f->frequency > GEMTEK_PCI_RANGE_HIGH) ) 237 (f->frequency > GEMTEK_PCI_RANGE_HIGH) )
@@ -248,8 +245,7 @@ static int vidioc_s_frequency(struct file *file, void *priv,
248static int vidioc_g_frequency(struct file *file, void *priv, 245static int vidioc_g_frequency(struct file *file, void *priv,
249 struct v4l2_frequency *f) 246 struct v4l2_frequency *f)
250{ 247{
251 struct video_device *dev = video_devdata(file); 248 struct gemtek_pci_card *card = video_drvdata(file);
252 struct gemtek_pci_card *card = dev->priv;
253 249
254 f->type = V4L2_TUNER_RADIO; 250 f->type = V4L2_TUNER_RADIO;
255 f->frequency = card->current_frequency; 251 f->frequency = card->current_frequency;
@@ -273,8 +269,7 @@ static int vidioc_queryctrl(struct file *file, void *priv,
273static int vidioc_g_ctrl(struct file *file, void *priv, 269static int vidioc_g_ctrl(struct file *file, void *priv,
274 struct v4l2_control *ctrl) 270 struct v4l2_control *ctrl)
275{ 271{
276 struct video_device *dev = video_devdata(file); 272 struct gemtek_pci_card *card = video_drvdata(file);
277 struct gemtek_pci_card *card = dev->priv;
278 273
279 switch (ctrl->id) { 274 switch (ctrl->id) {
280 case V4L2_CID_AUDIO_MUTE: 275 case V4L2_CID_AUDIO_MUTE:
@@ -293,8 +288,7 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
293static int vidioc_s_ctrl(struct file *file, void *priv, 288static int vidioc_s_ctrl(struct file *file, void *priv,
294 struct v4l2_control *ctrl) 289 struct v4l2_control *ctrl)
295{ 290{
296 struct video_device *dev = video_devdata(file); 291 struct gemtek_pci_card *card = video_drvdata(file);
297 struct gemtek_pci_card *card = dev->priv;
298 292
299 switch (ctrl->id) { 293 switch (ctrl->id) {
300 case V4L2_CID_AUDIO_MUTE: 294 case V4L2_CID_AUDIO_MUTE:
@@ -364,10 +358,21 @@ MODULE_DEVICE_TABLE( pci, gemtek_pci_id );
364 358
365static int mx = 1; 359static int mx = 1;
366 360
361static int gemtek_pci_exclusive_open(struct inode *inode, struct file *file)
362{
363 return test_and_set_bit(0, &in_use) ? -EBUSY : 0;
364}
365
366static int gemtek_pci_exclusive_release(struct inode *inode, struct file *file)
367{
368 clear_bit(0, &in_use);
369 return 0;
370}
371
367static const struct file_operations gemtek_pci_fops = { 372static const struct file_operations gemtek_pci_fops = {
368 .owner = THIS_MODULE, 373 .owner = THIS_MODULE,
369 .open = video_exclusive_open, 374 .open = gemtek_pci_exclusive_open,
370 .release = video_exclusive_release, 375 .release = gemtek_pci_exclusive_release,
371 .ioctl = video_ioctl2, 376 .ioctl = video_ioctl2,
372#ifdef CONFIG_COMPAT 377#ifdef CONFIG_COMPAT
373 .compat_ioctl = v4l_compat_ioctl32, 378 .compat_ioctl = v4l_compat_ioctl32,
@@ -391,9 +396,10 @@ static const struct v4l2_ioctl_ops gemtek_pci_ioctl_ops = {
391}; 396};
392 397
393static struct video_device vdev_template = { 398static struct video_device vdev_template = {
394 .name = "Gemtek PCI Radio", 399 .name = "Gemtek PCI Radio",
395 .fops = &gemtek_pci_fops, 400 .fops = &gemtek_pci_fops,
396 .ioctl_ops = &gemtek_pci_ioctl_ops, 401 .ioctl_ops = &gemtek_pci_ioctl_ops,
402 .release = video_device_release_empty,
397}; 403};
398 404
399static int __devinit gemtek_pci_probe( struct pci_dev *pci_dev, const struct pci_device_id *pci_id ) 405static int __devinit gemtek_pci_probe( struct pci_dev *pci_dev, const struct pci_device_id *pci_id )
@@ -431,7 +437,7 @@ static int __devinit gemtek_pci_probe( struct pci_dev *pci_dev, const struct pci
431 } 437 }
432 438
433 card->videodev = devradio; 439 card->videodev = devradio;
434 devradio->priv = card; 440 video_set_drvdata(devradio, card);
435 gemtek_pci_mute( card ); 441 gemtek_pci_mute( card );
436 442
437 printk( KERN_INFO "Gemtek PCI Radio (rev. %d) found at 0x%04x-0x%04x.\n", 443 printk( KERN_INFO "Gemtek PCI Radio (rev. %d) found at 0x%04x-0x%04x.\n",
diff --git a/drivers/media/radio/radio-gemtek.c b/drivers/media/radio/radio-gemtek.c
index 0a0f956bb308..d131a5d38128 100644
--- a/drivers/media/radio/radio-gemtek.c
+++ b/drivers/media/radio/radio-gemtek.c
@@ -57,6 +57,7 @@ static int shutdown = 1;
57static int keepmuted = 1; 57static int keepmuted = 1;
58static int initmute = 1; 58static int initmute = 1;
59static int radio_nr = -1; 59static int radio_nr = -1;
60static unsigned long in_use;
60 61
61module_param(io, int, 0444); 62module_param(io, int, 0444);
62MODULE_PARM_DESC(io, "Force I/O port for the GemTek Radio card if automatic " 63MODULE_PARM_DESC(io, "Force I/O port for the GemTek Radio card if automatic "
@@ -393,10 +394,21 @@ static struct v4l2_queryctrl radio_qctrl[] = {
393 } 394 }
394}; 395};
395 396
397static int gemtek_exclusive_open(struct inode *inode, struct file *file)
398{
399 return test_and_set_bit(0, &in_use) ? -EBUSY : 0;
400}
401
402static int gemtek_exclusive_release(struct inode *inode, struct file *file)
403{
404 clear_bit(0, &in_use);
405 return 0;
406}
407
396static const struct file_operations gemtek_fops = { 408static const struct file_operations gemtek_fops = {
397 .owner = THIS_MODULE, 409 .owner = THIS_MODULE,
398 .open = video_exclusive_open, 410 .open = gemtek_exclusive_open,
399 .release = video_exclusive_release, 411 .release = gemtek_exclusive_release,
400 .ioctl = video_ioctl2, 412 .ioctl = video_ioctl2,
401#ifdef CONFIG_COMPAT 413#ifdef CONFIG_COMPAT
402 .compat_ioctl = v4l_compat_ioctl32, 414 .compat_ioctl = v4l_compat_ioctl32,
@@ -447,8 +459,7 @@ static int vidioc_s_tuner(struct file *file, void *priv, struct v4l2_tuner *v)
447static int vidioc_s_frequency(struct file *file, void *priv, 459static int vidioc_s_frequency(struct file *file, void *priv,
448 struct v4l2_frequency *f) 460 struct v4l2_frequency *f)
449{ 461{
450 struct video_device *dev = video_devdata(file); 462 struct gemtek_device *rt = video_drvdata(file);
451 struct gemtek_device *rt = dev->priv;
452 463
453 gemtek_setfreq(rt, f->frequency); 464 gemtek_setfreq(rt, f->frequency);
454 465
@@ -458,8 +469,7 @@ static int vidioc_s_frequency(struct file *file, void *priv,
458static int vidioc_g_frequency(struct file *file, void *priv, 469static int vidioc_g_frequency(struct file *file, void *priv,
459 struct v4l2_frequency *f) 470 struct v4l2_frequency *f)
460{ 471{
461 struct video_device *dev = video_devdata(file); 472 struct gemtek_device *rt = video_drvdata(file);
462 struct gemtek_device *rt = dev->priv;
463 473
464 f->type = V4L2_TUNER_RADIO; 474 f->type = V4L2_TUNER_RADIO;
465 f->frequency = rt->lastfreq; 475 f->frequency = rt->lastfreq;
@@ -483,8 +493,7 @@ static int vidioc_queryctrl(struct file *file, void *priv,
483static int vidioc_g_ctrl(struct file *file, void *priv, 493static int vidioc_g_ctrl(struct file *file, void *priv,
484 struct v4l2_control *ctrl) 494 struct v4l2_control *ctrl)
485{ 495{
486 struct video_device *dev = video_devdata(file); 496 struct gemtek_device *rt = video_drvdata(file);
487 struct gemtek_device *rt = dev->priv;
488 497
489 switch (ctrl->id) { 498 switch (ctrl->id) {
490 case V4L2_CID_AUDIO_MUTE: 499 case V4L2_CID_AUDIO_MUTE:
@@ -503,8 +512,7 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
503static int vidioc_s_ctrl(struct file *file, void *priv, 512static int vidioc_s_ctrl(struct file *file, void *priv,
504 struct v4l2_control *ctrl) 513 struct v4l2_control *ctrl)
505{ 514{
506 struct video_device *dev = video_devdata(file); 515 struct gemtek_device *rt = video_drvdata(file);
507 struct gemtek_device *rt = dev->priv;
508 516
509 switch (ctrl->id) { 517 switch (ctrl->id) {
510 case V4L2_CID_AUDIO_MUTE: 518 case V4L2_CID_AUDIO_MUTE:
@@ -569,9 +577,10 @@ static const struct v4l2_ioctl_ops gemtek_ioctl_ops = {
569}; 577};
570 578
571static struct video_device gemtek_radio = { 579static struct video_device gemtek_radio = {
572 .name = "GemTek Radio card", 580 .name = "GemTek Radio card",
573 .fops = &gemtek_fops, 581 .fops = &gemtek_fops,
574 .ioctl_ops = &gemtek_ioctl_ops, 582 .ioctl_ops = &gemtek_ioctl_ops,
583 .release = video_device_release_empty,
575}; 584};
576 585
577/* 586/*
@@ -610,7 +619,7 @@ static int __init gemtek_init(void)
610 return -EINVAL; 619 return -EINVAL;
611 } 620 }
612 621
613 gemtek_radio.priv = &gemtek_unit; 622 video_set_drvdata(&gemtek_radio, &gemtek_unit);
614 623
615 if (video_register_device(&gemtek_radio, VFL_TYPE_RADIO, radio_nr) < 0) { 624 if (video_register_device(&gemtek_radio, VFL_TYPE_RADIO, radio_nr) < 0) {
616 release_region(io, 1); 625 release_region(io, 1);
diff --git a/drivers/media/radio/radio-maestro.c b/drivers/media/radio/radio-maestro.c
index 9ef0a763eeb7..4bf4d007bcfa 100644
--- a/drivers/media/radio/radio-maestro.c
+++ b/drivers/media/radio/radio-maestro.c
@@ -75,7 +75,21 @@ static struct v4l2_queryctrl radio_qctrl[] = {
75static int radio_nr = -1; 75static int radio_nr = -1;
76module_param(radio_nr, int, 0); 76module_param(radio_nr, int, 0);
77 77
78static unsigned long in_use;
79
78static int maestro_probe(struct pci_dev *pdev, const struct pci_device_id *ent); 80static int maestro_probe(struct pci_dev *pdev, const struct pci_device_id *ent);
81
82static int maestro_exclusive_open(struct inode *inode, struct file *file)
83{
84 return test_and_set_bit(0, &in_use) ? -EBUSY : 0;
85}
86
87static int maestro_exclusive_release(struct inode *inode, struct file *file)
88{
89 clear_bit(0, &in_use);
90 return 0;
91}
92
79static void maestro_remove(struct pci_dev *pdev); 93static void maestro_remove(struct pci_dev *pdev);
80 94
81static struct pci_device_id maestro_r_pci_tbl[] = { 95static struct pci_device_id maestro_r_pci_tbl[] = {
@@ -98,8 +112,8 @@ static struct pci_driver maestro_r_driver = {
98 112
99static const struct file_operations maestro_fops = { 113static const struct file_operations maestro_fops = {
100 .owner = THIS_MODULE, 114 .owner = THIS_MODULE,
101 .open = video_exclusive_open, 115 .open = maestro_exclusive_open,
102 .release = video_exclusive_release, 116 .release = maestro_exclusive_release,
103 .ioctl = video_ioctl2, 117 .ioctl = video_ioctl2,
104#ifdef CONFIG_COMPAT 118#ifdef CONFIG_COMPAT
105 .compat_ioctl = v4l_compat_ioctl32, 119 .compat_ioctl = v4l_compat_ioctl32,
@@ -196,8 +210,7 @@ static int vidioc_querycap(struct file *file, void *priv,
196static int vidioc_g_tuner(struct file *file, void *priv, 210static int vidioc_g_tuner(struct file *file, void *priv,
197 struct v4l2_tuner *v) 211 struct v4l2_tuner *v)
198{ 212{
199 struct video_device *dev = video_devdata(file); 213 struct radio_device *card = video_drvdata(file);
200 struct radio_device *card = video_get_drvdata(dev);
201 214
202 if (v->index > 0) 215 if (v->index > 0)
203 return -EINVAL; 216 return -EINVAL;
@@ -229,8 +242,7 @@ static int vidioc_s_tuner(struct file *file, void *priv,
229static int vidioc_s_frequency(struct file *file, void *priv, 242static int vidioc_s_frequency(struct file *file, void *priv,
230 struct v4l2_frequency *f) 243 struct v4l2_frequency *f)
231{ 244{
232 struct video_device *dev = video_devdata(file); 245 struct radio_device *card = video_drvdata(file);
233 struct radio_device *card = video_get_drvdata(dev);
234 246
235 if (f->frequency < FREQ_LO || f->frequency > FREQ_HI) 247 if (f->frequency < FREQ_LO || f->frequency > FREQ_HI)
236 return -EINVAL; 248 return -EINVAL;
@@ -241,8 +253,7 @@ static int vidioc_s_frequency(struct file *file, void *priv,
241static int vidioc_g_frequency(struct file *file, void *priv, 253static int vidioc_g_frequency(struct file *file, void *priv,
242 struct v4l2_frequency *f) 254 struct v4l2_frequency *f)
243{ 255{
244 struct video_device *dev = video_devdata(file); 256 struct radio_device *card = video_drvdata(file);
245 struct radio_device *card = video_get_drvdata(dev);
246 257
247 f->type = V4L2_TUNER_RADIO; 258 f->type = V4L2_TUNER_RADIO;
248 f->frequency = BITS2FREQ(radio_bits_get(card)); 259 f->frequency = BITS2FREQ(radio_bits_get(card));
@@ -267,8 +278,7 @@ static int vidioc_queryctrl(struct file *file, void *priv,
267static int vidioc_g_ctrl(struct file *file, void *priv, 278static int vidioc_g_ctrl(struct file *file, void *priv,
268 struct v4l2_control *ctrl) 279 struct v4l2_control *ctrl)
269{ 280{
270 struct video_device *dev = video_devdata(file); 281 struct radio_device *card = video_drvdata(file);
271 struct radio_device *card = video_get_drvdata(dev);
272 282
273 switch (ctrl->id) { 283 switch (ctrl->id) {
274 case V4L2_CID_AUDIO_MUTE: 284 case V4L2_CID_AUDIO_MUTE:
@@ -281,8 +291,7 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
281static int vidioc_s_ctrl(struct file *file, void *priv, 291static int vidioc_s_ctrl(struct file *file, void *priv,
282 struct v4l2_control *ctrl) 292 struct v4l2_control *ctrl)
283{ 293{
284 struct video_device *dev = video_devdata(file); 294 struct radio_device *card = video_drvdata(file);
285 struct radio_device *card = video_get_drvdata(dev);
286 register u16 io = card->io; 295 register u16 io = card->io;
287 register u16 omask = inw(io + IO_MASK); 296 register u16 omask = inw(io + IO_MASK);
288 297
@@ -374,6 +383,7 @@ static struct video_device maestro_radio = {
374 .name = "Maestro radio", 383 .name = "Maestro radio",
375 .fops = &maestro_fops, 384 .fops = &maestro_fops,
376 .ioctl_ops = &maestro_ioctl_ops, 385 .ioctl_ops = &maestro_ioctl_ops,
386 .release = video_device_release,
377}; 387};
378 388
379static int __devinit maestro_probe(struct pci_dev *pdev, 389static int __devinit maestro_probe(struct pci_dev *pdev,
diff --git a/drivers/media/radio/radio-maxiradio.c b/drivers/media/radio/radio-maxiradio.c
index 0cc6fcb041fd..c777a17b00bc 100644
--- a/drivers/media/radio/radio-maxiradio.c
+++ b/drivers/media/radio/radio-maxiradio.c
@@ -85,6 +85,7 @@ static const int clk = 1, data = 2, wren = 4, mo_st = 8, power = 16 ;
85static int radio_nr = -1; 85static int radio_nr = -1;
86module_param(radio_nr, int, 0); 86module_param(radio_nr, int, 0);
87 87
88static unsigned long in_use;
88 89
89#define FREQ_LO 50*16000 90#define FREQ_LO 50*16000
90#define FREQ_HI 150*16000 91#define FREQ_HI 150*16000
@@ -99,10 +100,21 @@ module_param(radio_nr, int, 0);
99#define BITS2FREQ(x) ((x) * FREQ_STEP - FREQ_IF) 100#define BITS2FREQ(x) ((x) * FREQ_STEP - FREQ_IF)
100 101
101 102
103static int maxiradio_exclusive_open(struct inode *inode, struct file *file)
104{
105 return test_and_set_bit(0, &in_use) ? -EBUSY : 0;
106}
107
108static int maxiradio_exclusive_release(struct inode *inode, struct file *file)
109{
110 clear_bit(0, &in_use);
111 return 0;
112}
113
102static const struct file_operations maxiradio_fops = { 114static const struct file_operations maxiradio_fops = {
103 .owner = THIS_MODULE, 115 .owner = THIS_MODULE,
104 .open = video_exclusive_open, 116 .open = maxiradio_exclusive_open,
105 .release = video_exclusive_release, 117 .release = maxiradio_exclusive_release,
106 .ioctl = video_ioctl2, 118 .ioctl = video_ioctl2,
107#ifdef CONFIG_COMPAT 119#ifdef CONFIG_COMPAT
108 .compat_ioctl = v4l_compat_ioctl32, 120 .compat_ioctl = v4l_compat_ioctl32,
@@ -219,8 +231,7 @@ static int vidioc_querycap (struct file *file, void *priv,
219static int vidioc_g_tuner (struct file *file, void *priv, 231static int vidioc_g_tuner (struct file *file, void *priv,
220 struct v4l2_tuner *v) 232 struct v4l2_tuner *v)
221{ 233{
222 struct video_device *dev = video_devdata(file); 234 struct radio_device *card = video_drvdata(file);
223 struct radio_device *card=dev->priv;
224 235
225 if (v->index > 0) 236 if (v->index > 0)
226 return -EINVAL; 237 return -EINVAL;
@@ -290,8 +301,7 @@ static int vidioc_s_audio (struct file *file, void *priv,
290static int vidioc_s_frequency (struct file *file, void *priv, 301static int vidioc_s_frequency (struct file *file, void *priv,
291 struct v4l2_frequency *f) 302 struct v4l2_frequency *f)
292{ 303{
293 struct video_device *dev = video_devdata(file); 304 struct radio_device *card = video_drvdata(file);
294 struct radio_device *card=dev->priv;
295 305
296 if (f->frequency < FREQ_LO || f->frequency > FREQ_HI) { 306 if (f->frequency < FREQ_LO || f->frequency > FREQ_HI) {
297 dprintk(1, "radio freq (%d.%02d MHz) out of range (%d-%d)\n", 307 dprintk(1, "radio freq (%d.%02d MHz) out of range (%d-%d)\n",
@@ -312,8 +322,7 @@ static int vidioc_s_frequency (struct file *file, void *priv,
312static int vidioc_g_frequency (struct file *file, void *priv, 322static int vidioc_g_frequency (struct file *file, void *priv,
313 struct v4l2_frequency *f) 323 struct v4l2_frequency *f)
314{ 324{
315 struct video_device *dev = video_devdata(file); 325 struct radio_device *card = video_drvdata(file);
316 struct radio_device *card=dev->priv;
317 326
318 f->type = V4L2_TUNER_RADIO; 327 f->type = V4L2_TUNER_RADIO;
319 f->frequency = card->freq; 328 f->frequency = card->freq;
@@ -343,8 +352,7 @@ static int vidioc_queryctrl (struct file *file, void *priv,
343static int vidioc_g_ctrl (struct file *file, void *priv, 352static int vidioc_g_ctrl (struct file *file, void *priv,
344 struct v4l2_control *ctrl) 353 struct v4l2_control *ctrl)
345{ 354{
346 struct video_device *dev = video_devdata(file); 355 struct radio_device *card = video_drvdata(file);
347 struct radio_device *card=dev->priv;
348 356
349 switch (ctrl->id) { 357 switch (ctrl->id) {
350 case V4L2_CID_AUDIO_MUTE: 358 case V4L2_CID_AUDIO_MUTE:
@@ -358,8 +366,7 @@ static int vidioc_g_ctrl (struct file *file, void *priv,
358static int vidioc_s_ctrl (struct file *file, void *priv, 366static int vidioc_s_ctrl (struct file *file, void *priv,
359 struct v4l2_control *ctrl) 367 struct v4l2_control *ctrl)
360{ 368{
361 struct video_device *dev = video_devdata(file); 369 struct radio_device *card = video_drvdata(file);
362 struct radio_device *card=dev->priv;
363 370
364 switch (ctrl->id) { 371 switch (ctrl->id) {
365 case V4L2_CID_AUDIO_MUTE: 372 case V4L2_CID_AUDIO_MUTE:
@@ -390,9 +397,10 @@ static const struct v4l2_ioctl_ops maxiradio_ioctl_ops = {
390}; 397};
391 398
392static struct video_device maxiradio_radio = { 399static struct video_device maxiradio_radio = {
393 .name = "Maxi Radio FM2000 radio", 400 .name = "Maxi Radio FM2000 radio",
394 .fops = &maxiradio_fops, 401 .fops = &maxiradio_fops,
395 .ioctl_ops = &maxiradio_ioctl_ops, 402 .ioctl_ops = &maxiradio_ioctl_ops,
403 .release = video_device_release_empty,
396}; 404};
397 405
398static int __devinit maxiradio_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) 406static int __devinit maxiradio_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
@@ -408,7 +416,7 @@ static int __devinit maxiradio_init_one(struct pci_dev *pdev, const struct pci_d
408 416
409 radio_unit.io = pci_resource_start(pdev, 0); 417 radio_unit.io = pci_resource_start(pdev, 0);
410 mutex_init(&radio_unit.lock); 418 mutex_init(&radio_unit.lock);
411 maxiradio_radio.priv = &radio_unit; 419 video_set_drvdata(&maxiradio_radio, &radio_unit);
412 420
413 if (video_register_device(&maxiradio_radio, VFL_TYPE_RADIO, radio_nr) < 0) { 421 if (video_register_device(&maxiradio_radio, VFL_TYPE_RADIO, radio_nr) < 0) {
414 printk("radio-maxiradio: can't register device!"); 422 printk("radio-maxiradio: can't register device!");
diff --git a/drivers/media/radio/radio-mr800.c b/drivers/media/radio/radio-mr800.c
new file mode 100644
index 000000000000..a33717c48003
--- /dev/null
+++ b/drivers/media/radio/radio-mr800.c
@@ -0,0 +1,628 @@
1/*
2 * A driver for the AverMedia MR 800 USB FM radio. This device plugs
3 * into both the USB and an analog audio input, so this thing
4 * only deals with initialization and frequency setting, the
5 * audio data has to be handled by a sound driver.
6 *
7 * Copyright (c) 2008 Alexey Klimov <klimov.linux@gmail.com>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
23
24/*
25 * Big thanks to authors of dsbr100.c and radio-si470x.c
26 *
27 * When work was looked pretty good, i discover this:
28 * http://av-usbradio.sourceforge.net/index.php
29 * http://sourceforge.net/projects/av-usbradio/
30 * Latest release of theirs project was in 2005.
31 * Probably, this driver could be improved trough using their
32 * achievements (specifications given).
33 * So, we have smth to begin with.
34 *
35 * History:
36 * Version 0.01: First working version.
37 * It's required to blacklist AverMedia USB Radio
38 * in usbhid/hid-quirks.c
39 *
40 * Many things to do:
41 * - Correct power managment of device (suspend & resume)
42 * - Make x86 independance (little-endian and big-endian stuff)
43 * - Add code for scanning and smooth tuning
44 * - Checked and add stereo&mono stuff
45 * - Add code for sensitivity value
46 * - Correct mistakes
47 * - In Japan another FREQ_MIN and FREQ_MAX
48 */
49
50/* kernel includes */
51#include <linux/kernel.h>
52#include <linux/module.h>
53#include <linux/init.h>
54#include <linux/slab.h>
55#include <linux/input.h>
56#include <linux/videodev2.h>
57#include <media/v4l2-common.h>
58#include <media/v4l2-ioctl.h>
59#include <linux/usb.h>
60#include <linux/version.h> /* for KERNEL_VERSION MACRO */
61
62/* driver and module definitions */
63#define DRIVER_AUTHOR "Alexey Klimov <klimov.linux@gmail.com>"
64#define DRIVER_DESC "AverMedia MR 800 USB FM radio driver"
65#define DRIVER_VERSION "0.01"
66#define RADIO_VERSION KERNEL_VERSION(0, 0, 1)
67
68MODULE_AUTHOR(DRIVER_AUTHOR);
69MODULE_DESCRIPTION(DRIVER_DESC);
70MODULE_LICENSE("GPL");
71
72#define USB_AMRADIO_VENDOR 0x07ca
73#define USB_AMRADIO_PRODUCT 0xb800
74
75/* Probably USB_TIMEOUT should be modified in module parameter */
76#define BUFFER_LENGTH 8
77#define USB_TIMEOUT 500
78
79/* Frequency limits in MHz -- these are European values. For Japanese
80devices, that would be 76 and 91. */
81#define FREQ_MIN 87.5
82#define FREQ_MAX 108.0
83#define FREQ_MUL 16000
84
85/* module parameter */
86static int radio_nr = -1;
87module_param(radio_nr, int, 0);
88MODULE_PARM_DESC(radio_nr, "Radio Nr");
89
90static struct v4l2_queryctrl radio_qctrl[] = {
91 {
92 .id = V4L2_CID_AUDIO_MUTE,
93 .name = "Mute",
94 .minimum = 0,
95 .maximum = 1,
96 .step = 1,
97 .default_value = 1,
98 .type = V4L2_CTRL_TYPE_BOOLEAN,
99 },
100/* HINT: the disabled controls are only here to satify kradio and such apps */
101 { .id = V4L2_CID_AUDIO_VOLUME,
102 .flags = V4L2_CTRL_FLAG_DISABLED,
103 },
104 {
105 .id = V4L2_CID_AUDIO_BALANCE,
106 .flags = V4L2_CTRL_FLAG_DISABLED,
107 },
108 {
109 .id = V4L2_CID_AUDIO_BASS,
110 .flags = V4L2_CTRL_FLAG_DISABLED,
111 },
112 {
113 .id = V4L2_CID_AUDIO_TREBLE,
114 .flags = V4L2_CTRL_FLAG_DISABLED,
115 },
116 {
117 .id = V4L2_CID_AUDIO_LOUDNESS,
118 .flags = V4L2_CTRL_FLAG_DISABLED,
119 },
120};
121
122static int usb_amradio_probe(struct usb_interface *intf,
123 const struct usb_device_id *id);
124static void usb_amradio_disconnect(struct usb_interface *intf);
125static int usb_amradio_open(struct inode *inode, struct file *file);
126static int usb_amradio_close(struct inode *inode, struct file *file);
127static int usb_amradio_suspend(struct usb_interface *intf,
128 pm_message_t message);
129static int usb_amradio_resume(struct usb_interface *intf);
130
131/* Data for one (physical) device */
132struct amradio_device {
133 /* reference to USB and video device */
134 struct usb_device *usbdev;
135 struct video_device *videodev;
136
137 unsigned char *buffer;
138 struct mutex lock; /* buffer locking */
139 int curfreq;
140 int stereo;
141 int users;
142 int removed;
143 int muted;
144};
145
146/* USB Device ID List */
147static struct usb_device_id usb_amradio_device_table[] = {
148 {USB_DEVICE_AND_INTERFACE_INFO(USB_AMRADIO_VENDOR, USB_AMRADIO_PRODUCT,
149 USB_CLASS_HID, 0, 0) },
150 { } /* Terminating entry */
151};
152
153MODULE_DEVICE_TABLE(usb, usb_amradio_device_table);
154
155/* USB subsystem interface */
156static struct usb_driver usb_amradio_driver = {
157 .name = "radio-mr800",
158 .probe = usb_amradio_probe,
159 .disconnect = usb_amradio_disconnect,
160 .suspend = usb_amradio_suspend,
161 .resume = usb_amradio_resume,
162 .reset_resume = usb_amradio_resume,
163 .id_table = usb_amradio_device_table,
164 .supports_autosuspend = 1,
165};
166
167/* switch on radio. Send 8 bytes to device. */
168static int amradio_start(struct amradio_device *radio)
169{
170 int retval;
171 int size;
172
173 mutex_lock(&radio->lock);
174
175 radio->buffer[0] = 0x00;
176 radio->buffer[1] = 0x55;
177 radio->buffer[2] = 0xaa;
178 radio->buffer[3] = 0x00;
179 radio->buffer[4] = 0xab;
180 radio->buffer[5] = 0x00;
181 radio->buffer[6] = 0x00;
182 radio->buffer[7] = 0x00;
183
184 retval = usb_bulk_msg(radio->usbdev, usb_sndintpipe(radio->usbdev, 2),
185 (void *) (radio->buffer), BUFFER_LENGTH, &size, USB_TIMEOUT);
186
187 if (retval) {
188 mutex_unlock(&radio->lock);
189 return retval;
190 }
191
192 mutex_unlock(&radio->lock);
193
194 radio->muted = 0;
195
196 return retval;
197}
198
199/* switch off radio */
200static int amradio_stop(struct amradio_device *radio)
201{
202 int retval;
203 int size;
204
205 mutex_lock(&radio->lock);
206
207 radio->buffer[0] = 0x00;
208 radio->buffer[1] = 0x55;
209 radio->buffer[2] = 0xaa;
210 radio->buffer[3] = 0x00;
211 radio->buffer[4] = 0xab;
212 radio->buffer[5] = 0x01;
213 radio->buffer[6] = 0x00;
214 radio->buffer[7] = 0x00;
215
216 retval = usb_bulk_msg(radio->usbdev, usb_sndintpipe(radio->usbdev, 2),
217 (void *) (radio->buffer), BUFFER_LENGTH, &size, USB_TIMEOUT);
218
219 if (retval) {
220 mutex_unlock(&radio->lock);
221 return retval;
222 }
223
224 mutex_unlock(&radio->lock);
225
226 radio->muted = 1;
227
228 return retval;
229}
230
231/* set a frequency, freq is defined by v4l's TUNER_LOW, i.e. 1/16th kHz */
232static int amradio_setfreq(struct amradio_device *radio, int freq)
233{
234 int retval;
235 int size;
236 unsigned short freq_send = 0x13 + (freq >> 3) / 25;
237
238 mutex_lock(&radio->lock);
239
240 radio->buffer[0] = 0x00;
241 radio->buffer[1] = 0x55;
242 radio->buffer[2] = 0xaa;
243 radio->buffer[3] = 0x03;
244 radio->buffer[4] = 0xa4;
245 radio->buffer[5] = 0x00;
246 radio->buffer[6] = 0x00;
247 radio->buffer[7] = 0x08;
248
249 retval = usb_bulk_msg(radio->usbdev, usb_sndintpipe(radio->usbdev, 2),
250 (void *) (radio->buffer), BUFFER_LENGTH, &size, USB_TIMEOUT);
251
252 if (retval) {
253 mutex_unlock(&radio->lock);
254 return retval;
255 }
256
257 /* frequency is calculated from freq_send and placed in first 2 bytes */
258 radio->buffer[0] = (freq_send >> 8) & 0xff;
259 radio->buffer[1] = freq_send & 0xff;
260 radio->buffer[2] = 0x01;
261 radio->buffer[3] = 0x00;
262 radio->buffer[4] = 0x00;
263 /* 5 and 6 bytes of buffer already = 0x00 */
264 radio->buffer[7] = 0x00;
265
266 retval = usb_bulk_msg(radio->usbdev, usb_sndintpipe(radio->usbdev, 2),
267 (void *) (radio->buffer), BUFFER_LENGTH, &size, USB_TIMEOUT);
268
269 if (retval) {
270 mutex_unlock(&radio->lock);
271 return retval;
272 }
273
274 mutex_unlock(&radio->lock);
275
276 radio->stereo = 0;
277
278 return retval;
279}
280
281/* USB subsystem interface begins here */
282
283/* handle unplugging of the device, release data structures
284if nothing keeps us from doing it. If something is still
285keeping us busy, the release callback of v4l will take care
286of releasing it. */
287static void usb_amradio_disconnect(struct usb_interface *intf)
288{
289 struct amradio_device *radio = usb_get_intfdata(intf);
290
291 usb_set_intfdata(intf, NULL);
292
293 if (radio) {
294 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}
304
305/* vidioc_querycap - query device capabilities */
306static int vidioc_querycap(struct file *file, void *priv,
307 struct v4l2_capability *v)
308{
309 strlcpy(v->driver, "radio-mr800", sizeof(v->driver));
310 strlcpy(v->card, "AverMedia MR 800 USB FM Radio", sizeof(v->card));
311 sprintf(v->bus_info, "USB");
312 v->version = RADIO_VERSION;
313 v->capabilities = V4L2_CAP_TUNER;
314 return 0;
315}
316
317/* vidioc_g_tuner - get tuner attributes */
318static int vidioc_g_tuner(struct file *file, void *priv,
319 struct v4l2_tuner *v)
320{
321 struct amradio_device *radio = video_get_drvdata(video_devdata(file));
322
323 if (v->index > 0)
324 return -EINVAL;
325
326/* TODO: Add function which look is signal stereo or not
327 * amradio_getstat(radio);
328 */
329 radio->stereo = -1;
330 strcpy(v->name, "FM");
331 v->type = V4L2_TUNER_RADIO;
332 v->rangelow = FREQ_MIN * FREQ_MUL;
333 v->rangehigh = FREQ_MAX * FREQ_MUL;
334 v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
335 v->capability = V4L2_TUNER_CAP_LOW;
336 if (radio->stereo)
337 v->audmode = V4L2_TUNER_MODE_STEREO;
338 else
339 v->audmode = V4L2_TUNER_MODE_MONO;
340 v->signal = 0xffff; /* Can't get the signal strength, sad.. */
341 v->afc = 0; /* Don't know what is this */
342 return 0;
343}
344
345/* vidioc_s_tuner - set tuner attributes */
346static int vidioc_s_tuner(struct file *file, void *priv,
347 struct v4l2_tuner *v)
348{
349 if (v->index > 0)
350 return -EINVAL;
351 return 0;
352}
353
354/* vidioc_s_frequency - set tuner radio frequency */
355static int vidioc_s_frequency(struct file *file, void *priv,
356 struct v4l2_frequency *f)
357{
358 struct amradio_device *radio = video_get_drvdata(video_devdata(file));
359
360 radio->curfreq = f->frequency;
361 if (amradio_setfreq(radio, radio->curfreq) < 0)
362 warn("Set frequency failed");
363 return 0;
364}
365
366/* vidioc_g_frequency - get tuner radio frequency */
367static int vidioc_g_frequency(struct file *file, void *priv,
368 struct v4l2_frequency *f)
369{
370 struct amradio_device *radio = video_get_drvdata(video_devdata(file));
371
372 f->type = V4L2_TUNER_RADIO;
373 f->frequency = radio->curfreq;
374 return 0;
375}
376
377/* vidioc_queryctrl - enumerate control items */
378static int vidioc_queryctrl(struct file *file, void *priv,
379 struct v4l2_queryctrl *qc)
380{
381 int i;
382
383 for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
384 if (qc->id && qc->id == radio_qctrl[i].id) {
385 memcpy(qc, &(radio_qctrl[i]),
386 sizeof(*qc));
387 return 0;
388 }
389 }
390 return -EINVAL;
391}
392
393/* vidioc_g_ctrl - get the value of a control */
394static int vidioc_g_ctrl(struct file *file, void *priv,
395 struct v4l2_control *ctrl)
396{
397 struct amradio_device *radio = video_get_drvdata(video_devdata(file));
398
399 switch (ctrl->id) {
400 case V4L2_CID_AUDIO_MUTE:
401 ctrl->value = radio->muted;
402 return 0;
403 }
404 return -EINVAL;
405}
406
407/* vidioc_s_ctrl - set the value of a control */
408static int vidioc_s_ctrl(struct file *file, void *priv,
409 struct v4l2_control *ctrl)
410{
411 struct amradio_device *radio = video_get_drvdata(video_devdata(file));
412
413 switch (ctrl->id) {
414 case V4L2_CID_AUDIO_MUTE:
415 if (ctrl->value) {
416 if (amradio_stop(radio) < 0) {
417 warn("amradio_stop() failed");
418 return -1;
419 }
420 } else {
421 if (amradio_start(radio) < 0) {
422 warn("amradio_start() failed");
423 return -1;
424 }
425 }
426 return 0;
427 }
428 return -EINVAL;
429}
430
431/* vidioc_g_audio - get audio attributes */
432static int vidioc_g_audio(struct file *file, void *priv,
433 struct v4l2_audio *a)
434{
435 if (a->index > 1)
436 return -EINVAL;
437
438 strcpy(a->name, "Radio");
439 a->capability = V4L2_AUDCAP_STEREO;
440 return 0;
441}
442
443/* vidioc_s_audio - set audio attributes */
444static int vidioc_s_audio(struct file *file, void *priv,
445 struct v4l2_audio *a)
446{
447 if (a->index != 0)
448 return -EINVAL;
449 return 0;
450}
451
452/* vidioc_g_input - get input */
453static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
454{
455 *i = 0;
456 return 0;
457}
458
459/* vidioc_s_input - set input */
460static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
461{
462 if (i != 0)
463 return -EINVAL;
464 return 0;
465}
466
467/* open device - amradio_start() and amradio_setfreq() */
468static int usb_amradio_open(struct inode *inode, struct file *file)
469{
470 struct amradio_device *radio = video_get_drvdata(video_devdata(file));
471
472 radio->users = 1;
473 radio->muted = 1;
474
475 if (amradio_start(radio) < 0) {
476 warn("Radio did not start up properly");
477 radio->users = 0;
478 return -EIO;
479 }
480 if (amradio_setfreq(radio, radio->curfreq) < 0)
481 warn("Set frequency failed");
482 return 0;
483}
484
485/*close device - free driver structures */
486static int usb_amradio_close(struct inode *inode, struct file *file)
487{
488 struct amradio_device *radio = video_get_drvdata(video_devdata(file));
489
490 if (!radio)
491 return -ENODEV;
492 radio->users = 0;
493 if (radio->removed) {
494 kfree(radio->buffer);
495 kfree(radio);
496 }
497 return 0;
498}
499
500/* Suspend device - stop device. Need to be checked and fixed */
501static int usb_amradio_suspend(struct usb_interface *intf, pm_message_t message)
502{
503 struct amradio_device *radio = usb_get_intfdata(intf);
504
505 if (amradio_stop(radio) < 0)
506 warn("amradio_stop() failed");
507
508 info("radio-mr800: Going into suspend..");
509
510 return 0;
511}
512
513/* Resume device - start device. Need to be checked and fixed */
514static int usb_amradio_resume(struct usb_interface *intf)
515{
516 struct amradio_device *radio = usb_get_intfdata(intf);
517
518 if (amradio_start(radio) < 0)
519 warn("amradio_start() failed");
520
521 info("radio-mr800: Coming out of suspend..");
522
523 return 0;
524}
525
526/* File system interface */
527static const struct file_operations usb_amradio_fops = {
528 .owner = THIS_MODULE,
529 .open = usb_amradio_open,
530 .release = usb_amradio_close,
531 .ioctl = video_ioctl2,
532#ifdef CONFIG_COMPAT
533 .compat_ioctl = v4l_compat_ioctl32,
534#endif
535 .llseek = no_llseek,
536};
537
538static const struct v4l2_ioctl_ops usb_amradio_ioctl_ops = {
539 .vidioc_querycap = vidioc_querycap,
540 .vidioc_g_tuner = vidioc_g_tuner,
541 .vidioc_s_tuner = vidioc_s_tuner,
542 .vidioc_g_frequency = vidioc_g_frequency,
543 .vidioc_s_frequency = vidioc_s_frequency,
544 .vidioc_queryctrl = vidioc_queryctrl,
545 .vidioc_g_ctrl = vidioc_g_ctrl,
546 .vidioc_s_ctrl = vidioc_s_ctrl,
547 .vidioc_g_audio = vidioc_g_audio,
548 .vidioc_s_audio = vidioc_s_audio,
549 .vidioc_g_input = vidioc_g_input,
550 .vidioc_s_input = vidioc_s_input,
551};
552
553/* V4L2 interface */
554static struct video_device amradio_videodev_template = {
555 .name = "AverMedia MR 800 USB FM Radio",
556 .fops = &usb_amradio_fops,
557 .ioctl_ops = &usb_amradio_ioctl_ops,
558 .release = video_device_release,
559};
560
561/* check if the device is present and register with v4l and
562usb if it is */
563static int usb_amradio_probe(struct usb_interface *intf,
564 const struct usb_device_id *id)
565{
566 struct amradio_device *radio;
567
568 radio = kmalloc(sizeof(struct amradio_device), GFP_KERNEL);
569
570 if (!(radio))
571 return -ENOMEM;
572
573 radio->buffer = kmalloc(BUFFER_LENGTH, GFP_KERNEL);
574
575 if (!(radio->buffer)) {
576 kfree(radio);
577 return -ENOMEM;
578 }
579
580 radio->videodev = video_device_alloc();
581
582 if (!(radio->videodev)) {
583 kfree(radio->buffer);
584 kfree(radio);
585 return -ENOMEM;
586 }
587
588 memcpy(radio->videodev, &amradio_videodev_template,
589 sizeof(amradio_videodev_template));
590
591 radio->removed = 0;
592 radio->users = 0;
593 radio->usbdev = interface_to_usbdev(intf);
594 radio->curfreq = 95.16 * FREQ_MUL;
595
596 mutex_init(&radio->lock);
597
598 video_set_drvdata(radio->videodev, radio);
599 if (video_register_device(radio->videodev, VFL_TYPE_RADIO, radio_nr)) {
600 warn("Could not register video device");
601 video_device_release(radio->videodev);
602 kfree(radio->buffer);
603 kfree(radio);
604 return -EIO;
605 }
606
607 usb_set_intfdata(intf, radio);
608 return 0;
609}
610
611static int __init amradio_init(void)
612{
613 int retval = usb_register(&usb_amradio_driver);
614
615 info(DRIVER_VERSION " " DRIVER_DESC);
616 if (retval)
617 err("usb_register failed. Error number %d", retval);
618 return retval;
619}
620
621static void __exit amradio_exit(void)
622{
623 usb_deregister(&usb_amradio_driver);
624}
625
626module_init(amradio_init);
627module_exit(amradio_exit);
628
diff --git a/drivers/media/radio/radio-rtrack2.c b/drivers/media/radio/radio-rtrack2.c
index 6d820e2481e7..a67079777419 100644
--- a/drivers/media/radio/radio-rtrack2.c
+++ b/drivers/media/radio/radio-rtrack2.c
@@ -52,6 +52,7 @@ static spinlock_t lock;
52 52
53struct rt_device 53struct rt_device
54{ 54{
55 unsigned long in_use;
55 int port; 56 int port;
56 unsigned long curfreq; 57 unsigned long curfreq;
57 int muted; 58 int muted;
@@ -153,8 +154,7 @@ static int rt_getsigstr(struct rt_device *dev)
153static int vidioc_g_tuner(struct file *file, void *priv, 154static int vidioc_g_tuner(struct file *file, void *priv,
154 struct v4l2_tuner *v) 155 struct v4l2_tuner *v)
155{ 156{
156 struct video_device *dev = video_devdata(file); 157 struct rt_device *rt = video_drvdata(file);
157 struct rt_device *rt = dev->priv;
158 158
159 if (v->index > 0) 159 if (v->index > 0)
160 return -EINVAL; 160 return -EINVAL;
@@ -173,8 +173,7 @@ static int vidioc_g_tuner(struct file *file, void *priv,
173static int vidioc_s_frequency(struct file *file, void *priv, 173static int vidioc_s_frequency(struct file *file, void *priv,
174 struct v4l2_frequency *f) 174 struct v4l2_frequency *f)
175{ 175{
176 struct video_device *dev = video_devdata(file); 176 struct rt_device *rt = video_drvdata(file);
177 struct rt_device *rt = dev->priv;
178 177
179 rt->curfreq = f->frequency; 178 rt->curfreq = f->frequency;
180 rt_setfreq(rt, rt->curfreq); 179 rt_setfreq(rt, rt->curfreq);
@@ -184,8 +183,7 @@ static int vidioc_s_frequency(struct file *file, void *priv,
184static int vidioc_g_frequency(struct file *file, void *priv, 183static int vidioc_g_frequency(struct file *file, void *priv,
185 struct v4l2_frequency *f) 184 struct v4l2_frequency *f)
186{ 185{
187 struct video_device *dev = video_devdata(file); 186 struct rt_device *rt = video_drvdata(file);
188 struct rt_device *rt = dev->priv;
189 187
190 f->type = V4L2_TUNER_RADIO; 188 f->type = V4L2_TUNER_RADIO;
191 f->frequency = rt->curfreq; 189 f->frequency = rt->curfreq;
@@ -210,8 +208,7 @@ static int vidioc_queryctrl(struct file *file, void *priv,
210static int vidioc_g_ctrl(struct file *file, void *priv, 208static int vidioc_g_ctrl(struct file *file, void *priv,
211 struct v4l2_control *ctrl) 209 struct v4l2_control *ctrl)
212{ 210{
213 struct video_device *dev = video_devdata(file); 211 struct rt_device *rt = video_drvdata(file);
214 struct rt_device *rt = dev->priv;
215 212
216 switch (ctrl->id) { 213 switch (ctrl->id) {
217 case V4L2_CID_AUDIO_MUTE: 214 case V4L2_CID_AUDIO_MUTE:
@@ -230,8 +227,7 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
230static int vidioc_s_ctrl(struct file *file, void *priv, 227static int vidioc_s_ctrl(struct file *file, void *priv,
231 struct v4l2_control *ctrl) 228 struct v4l2_control *ctrl)
232{ 229{
233 struct video_device *dev = video_devdata(file); 230 struct rt_device *rt = video_drvdata(file);
234 struct rt_device *rt = dev->priv;
235 231
236 switch (ctrl->id) { 232 switch (ctrl->id) {
237 case V4L2_CID_AUDIO_MUTE: 233 case V4L2_CID_AUDIO_MUTE:
@@ -284,10 +280,21 @@ static int vidioc_s_audio(struct file *file, void *priv,
284 280
285static struct rt_device rtrack2_unit; 281static struct rt_device rtrack2_unit;
286 282
283static int rtrack2_exclusive_open(struct inode *inode, struct file *file)
284{
285 return test_and_set_bit(0, &rtrack2_unit.in_use) ? -EBUSY : 0;
286}
287
288static int rtrack2_exclusive_release(struct inode *inode, struct file *file)
289{
290 clear_bit(0, &rtrack2_unit.in_use);
291 return 0;
292}
293
287static const struct file_operations rtrack2_fops = { 294static const struct file_operations rtrack2_fops = {
288 .owner = THIS_MODULE, 295 .owner = THIS_MODULE,
289 .open = video_exclusive_open, 296 .open = rtrack2_exclusive_open,
290 .release = video_exclusive_release, 297 .release = rtrack2_exclusive_release,
291 .ioctl = video_ioctl2, 298 .ioctl = video_ioctl2,
292#ifdef CONFIG_COMPAT 299#ifdef CONFIG_COMPAT
293 .compat_ioctl = v4l_compat_ioctl32, 300 .compat_ioctl = v4l_compat_ioctl32,
@@ -314,6 +321,7 @@ static struct video_device rtrack2_radio = {
314 .name = "RadioTrack II radio", 321 .name = "RadioTrack II radio",
315 .fops = &rtrack2_fops, 322 .fops = &rtrack2_fops,
316 .ioctl_ops = &rtrack2_ioctl_ops, 323 .ioctl_ops = &rtrack2_ioctl_ops,
324 .release = video_device_release_empty,
317}; 325};
318 326
319static int __init rtrack2_init(void) 327static int __init rtrack2_init(void)
@@ -329,7 +337,7 @@ static int __init rtrack2_init(void)
329 return -EBUSY; 337 return -EBUSY;
330 } 338 }
331 339
332 rtrack2_radio.priv=&rtrack2_unit; 340 video_set_drvdata(&rtrack2_radio, &rtrack2_unit);
333 341
334 spin_lock_init(&lock); 342 spin_lock_init(&lock);
335 if (video_register_device(&rtrack2_radio, VFL_TYPE_RADIO, radio_nr) < 0) { 343 if (video_register_device(&rtrack2_radio, VFL_TYPE_RADIO, radio_nr) < 0) {
diff --git a/drivers/media/radio/radio-sf16fmi.c b/drivers/media/radio/radio-sf16fmi.c
index 0d478f54a907..329c90bddadd 100644
--- a/drivers/media/radio/radio-sf16fmi.c
+++ b/drivers/media/radio/radio-sf16fmi.c
@@ -45,6 +45,7 @@ static struct v4l2_queryctrl radio_qctrl[] = {
45 45
46struct fmi_device 46struct fmi_device
47{ 47{
48 unsigned long in_use;
48 int port; 49 int port;
49 int curvol; /* 1 or 0 */ 50 int curvol; /* 1 or 0 */
50 unsigned long curfreq; /* freq in kHz */ 51 unsigned long curfreq; /* freq in kHz */
@@ -146,8 +147,7 @@ static int vidioc_g_tuner(struct file *file, void *priv,
146 struct v4l2_tuner *v) 147 struct v4l2_tuner *v)
147{ 148{
148 int mult; 149 int mult;
149 struct video_device *dev = video_devdata(file); 150 struct fmi_device *fmi = video_drvdata(file);
150 struct fmi_device *fmi = dev->priv;
151 151
152 if (v->index > 0) 152 if (v->index > 0)
153 return -EINVAL; 153 return -EINVAL;
@@ -175,8 +175,7 @@ static int vidioc_s_tuner(struct file *file, void *priv,
175static int vidioc_s_frequency(struct file *file, void *priv, 175static int vidioc_s_frequency(struct file *file, void *priv,
176 struct v4l2_frequency *f) 176 struct v4l2_frequency *f)
177{ 177{
178 struct video_device *dev = video_devdata(file); 178 struct fmi_device *fmi = video_drvdata(file);
179 struct fmi_device *fmi = dev->priv;
180 179
181 if (!(fmi->flags & V4L2_TUNER_CAP_LOW)) 180 if (!(fmi->flags & V4L2_TUNER_CAP_LOW))
182 f->frequency *= 1000; 181 f->frequency *= 1000;
@@ -193,8 +192,7 @@ static int vidioc_s_frequency(struct file *file, void *priv,
193static int vidioc_g_frequency(struct file *file, void *priv, 192static int vidioc_g_frequency(struct file *file, void *priv,
194 struct v4l2_frequency *f) 193 struct v4l2_frequency *f)
195{ 194{
196 struct video_device *dev = video_devdata(file); 195 struct fmi_device *fmi = video_drvdata(file);
197 struct fmi_device *fmi = dev->priv;
198 196
199 f->type = V4L2_TUNER_RADIO; 197 f->type = V4L2_TUNER_RADIO;
200 f->frequency = fmi->curfreq; 198 f->frequency = fmi->curfreq;
@@ -221,8 +219,7 @@ static int vidioc_queryctrl(struct file *file, void *priv,
221static int vidioc_g_ctrl(struct file *file, void *priv, 219static int vidioc_g_ctrl(struct file *file, void *priv,
222 struct v4l2_control *ctrl) 220 struct v4l2_control *ctrl)
223{ 221{
224 struct video_device *dev = video_devdata(file); 222 struct fmi_device *fmi = video_drvdata(file);
225 struct fmi_device *fmi = dev->priv;
226 223
227 switch (ctrl->id) { 224 switch (ctrl->id) {
228 case V4L2_CID_AUDIO_MUTE: 225 case V4L2_CID_AUDIO_MUTE:
@@ -235,8 +232,7 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
235static int vidioc_s_ctrl(struct file *file, void *priv, 232static int vidioc_s_ctrl(struct file *file, void *priv,
236 struct v4l2_control *ctrl) 233 struct v4l2_control *ctrl)
237{ 234{
238 struct video_device *dev = video_devdata(file); 235 struct fmi_device *fmi = video_drvdata(file);
239 struct fmi_device *fmi = dev->priv;
240 236
241 switch (ctrl->id) { 237 switch (ctrl->id) {
242 case V4L2_CID_AUDIO_MUTE: 238 case V4L2_CID_AUDIO_MUTE:
@@ -284,10 +280,21 @@ static int vidioc_s_audio(struct file *file, void *priv,
284 280
285static struct fmi_device fmi_unit; 281static struct fmi_device fmi_unit;
286 282
283static int fmi_exclusive_open(struct inode *inode, struct file *file)
284{
285 return test_and_set_bit(0, &fmi_unit.in_use) ? -EBUSY : 0;
286}
287
288static int fmi_exclusive_release(struct inode *inode, struct file *file)
289{
290 clear_bit(0, &fmi_unit.in_use);
291 return 0;
292}
293
287static const struct file_operations fmi_fops = { 294static const struct file_operations fmi_fops = {
288 .owner = THIS_MODULE, 295 .owner = THIS_MODULE,
289 .open = video_exclusive_open, 296 .open = fmi_exclusive_open,
290 .release = video_exclusive_release, 297 .release = fmi_exclusive_release,
291 .ioctl = video_ioctl2, 298 .ioctl = video_ioctl2,
292#ifdef CONFIG_COMPAT 299#ifdef CONFIG_COMPAT
293 .compat_ioctl = v4l_compat_ioctl32, 300 .compat_ioctl = v4l_compat_ioctl32,
@@ -314,6 +321,7 @@ static struct video_device fmi_radio = {
314 .name = "SF16FMx radio", 321 .name = "SF16FMx radio",
315 .fops = &fmi_fops, 322 .fops = &fmi_fops,
316 .ioctl_ops = &fmi_ioctl_ops, 323 .ioctl_ops = &fmi_ioctl_ops,
324 .release = video_device_release_empty,
317}; 325};
318 326
319/* ladis: this is my card. does any other types exist? */ 327/* ladis: this is my card. does any other types exist? */
@@ -373,7 +381,7 @@ static int __init fmi_init(void)
373 fmi_unit.curvol = 0; 381 fmi_unit.curvol = 0;
374 fmi_unit.curfreq = 0; 382 fmi_unit.curfreq = 0;
375 fmi_unit.flags = V4L2_TUNER_CAP_LOW; 383 fmi_unit.flags = V4L2_TUNER_CAP_LOW;
376 fmi_radio.priv = &fmi_unit; 384 video_set_drvdata(&fmi_radio, &fmi_unit);
377 385
378 mutex_init(&lock); 386 mutex_init(&lock);
379 387
diff --git a/drivers/media/radio/radio-sf16fmr2.c b/drivers/media/radio/radio-sf16fmr2.c
index 6290553d24be..b1f47c322e02 100644
--- a/drivers/media/radio/radio-sf16fmr2.c
+++ b/drivers/media/radio/radio-sf16fmr2.c
@@ -64,6 +64,7 @@ static struct v4l2_queryctrl radio_qctrl[] = {
64/* this should be static vars for module size */ 64/* this should be static vars for module size */
65struct fmr2_device 65struct fmr2_device
66{ 66{
67 unsigned long in_use;
67 int port; 68 int port;
68 int curvol; /* 0-15 */ 69 int curvol; /* 0-15 */
69 int mute; 70 int mute;
@@ -229,8 +230,7 @@ static int vidioc_g_tuner(struct file *file, void *priv,
229 struct v4l2_tuner *v) 230 struct v4l2_tuner *v)
230{ 231{
231 int mult; 232 int mult;
232 struct video_device *dev = video_devdata(file); 233 struct fmr2_device *fmr2 = video_drvdata(file);
233 struct fmr2_device *fmr2 = dev->priv;
234 234
235 if (v->index > 0) 235 if (v->index > 0)
236 return -EINVAL; 236 return -EINVAL;
@@ -262,8 +262,7 @@ static int vidioc_s_tuner(struct file *file, void *priv,
262static int vidioc_s_frequency(struct file *file, void *priv, 262static int vidioc_s_frequency(struct file *file, void *priv,
263 struct v4l2_frequency *f) 263 struct v4l2_frequency *f)
264{ 264{
265 struct video_device *dev = video_devdata(file); 265 struct fmr2_device *fmr2 = video_drvdata(file);
266 struct fmr2_device *fmr2 = dev->priv;
267 266
268 if (!(fmr2->flags & V4L2_TUNER_CAP_LOW)) 267 if (!(fmr2->flags & V4L2_TUNER_CAP_LOW))
269 f->frequency *= 1000; 268 f->frequency *= 1000;
@@ -286,8 +285,7 @@ static int vidioc_s_frequency(struct file *file, void *priv,
286static int vidioc_g_frequency(struct file *file, void *priv, 285static int vidioc_g_frequency(struct file *file, void *priv,
287 struct v4l2_frequency *f) 286 struct v4l2_frequency *f)
288{ 287{
289 struct video_device *dev = video_devdata(file); 288 struct fmr2_device *fmr2 = video_drvdata(file);
290 struct fmr2_device *fmr2 = dev->priv;
291 289
292 f->type = V4L2_TUNER_RADIO; 290 f->type = V4L2_TUNER_RADIO;
293 f->frequency = fmr2->curfreq; 291 f->frequency = fmr2->curfreq;
@@ -313,8 +311,7 @@ static int vidioc_queryctrl(struct file *file, void *priv,
313static int vidioc_g_ctrl(struct file *file, void *priv, 311static int vidioc_g_ctrl(struct file *file, void *priv,
314 struct v4l2_control *ctrl) 312 struct v4l2_control *ctrl)
315{ 313{
316 struct video_device *dev = video_devdata(file); 314 struct fmr2_device *fmr2 = video_drvdata(file);
317 struct fmr2_device *fmr2 = dev->priv;
318 315
319 switch (ctrl->id) { 316 switch (ctrl->id) {
320 case V4L2_CID_AUDIO_MUTE: 317 case V4L2_CID_AUDIO_MUTE:
@@ -330,8 +327,7 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
330static int vidioc_s_ctrl(struct file *file, void *priv, 327static int vidioc_s_ctrl(struct file *file, void *priv,
331 struct v4l2_control *ctrl) 328 struct v4l2_control *ctrl)
332{ 329{
333 struct video_device *dev = video_devdata(file); 330 struct fmr2_device *fmr2 = video_drvdata(file);
334 struct fmr2_device *fmr2 = dev->priv;
335 331
336 switch (ctrl->id) { 332 switch (ctrl->id) {
337 case V4L2_CID_AUDIO_MUTE: 333 case V4L2_CID_AUDIO_MUTE:
@@ -400,10 +396,21 @@ static int vidioc_s_audio(struct file *file, void *priv,
400 396
401static struct fmr2_device fmr2_unit; 397static struct fmr2_device fmr2_unit;
402 398
399static int fmr2_exclusive_open(struct inode *inode, struct file *file)
400{
401 return test_and_set_bit(0, &fmr2_unit.in_use) ? -EBUSY : 0;
402}
403
404static int fmr2_exclusive_release(struct inode *inode, struct file *file)
405{
406 clear_bit(0, &fmr2_unit.in_use);
407 return 0;
408}
409
403static const struct file_operations fmr2_fops = { 410static const struct file_operations fmr2_fops = {
404 .owner = THIS_MODULE, 411 .owner = THIS_MODULE,
405 .open = video_exclusive_open, 412 .open = fmr2_exclusive_open,
406 .release = video_exclusive_release, 413 .release = fmr2_exclusive_release,
407 .ioctl = video_ioctl2, 414 .ioctl = video_ioctl2,
408#ifdef CONFIG_COMPAT 415#ifdef CONFIG_COMPAT
409 .compat_ioctl = v4l_compat_ioctl32, 416 .compat_ioctl = v4l_compat_ioctl32,
@@ -430,6 +437,7 @@ static struct video_device fmr2_radio = {
430 .name = "SF16FMR2 radio", 437 .name = "SF16FMR2 radio",
431 .fops = &fmr2_fops, 438 .fops = &fmr2_fops,
432 .ioctl_ops = &fmr2_ioctl_ops, 439 .ioctl_ops = &fmr2_ioctl_ops,
440 .release = video_device_release_empty,
433}; 441};
434 442
435static int __init fmr2_init(void) 443static int __init fmr2_init(void)
@@ -441,7 +449,7 @@ static int __init fmr2_init(void)
441 fmr2_unit.stereo = 1; 449 fmr2_unit.stereo = 1;
442 fmr2_unit.flags = V4L2_TUNER_CAP_LOW; 450 fmr2_unit.flags = V4L2_TUNER_CAP_LOW;
443 fmr2_unit.card_type = 0; 451 fmr2_unit.card_type = 0;
444 fmr2_radio.priv = &fmr2_unit; 452 video_set_drvdata(&fmr2_radio, &fmr2_unit);
445 453
446 mutex_init(&lock); 454 mutex_init(&lock);
447 455
diff --git a/drivers/media/radio/radio-si470x.c b/drivers/media/radio/radio-si470x.c
index 16c7ef20265c..f6cedcd3ab97 100644
--- a/drivers/media/radio/radio-si470x.c
+++ b/drivers/media/radio/radio-si470x.c
@@ -986,7 +986,7 @@ static void si470x_work(struct work_struct *work)
986static ssize_t si470x_fops_read(struct file *file, char __user *buf, 986static ssize_t si470x_fops_read(struct file *file, char __user *buf,
987 size_t count, loff_t *ppos) 987 size_t count, loff_t *ppos)
988{ 988{
989 struct si470x_device *radio = video_get_drvdata(video_devdata(file)); 989 struct si470x_device *radio = video_drvdata(file);
990 int retval = 0; 990 int retval = 0;
991 unsigned int block_count = 0; 991 unsigned int block_count = 0;
992 992
@@ -1047,7 +1047,7 @@ done:
1047static unsigned int si470x_fops_poll(struct file *file, 1047static unsigned int si470x_fops_poll(struct file *file,
1048 struct poll_table_struct *pts) 1048 struct poll_table_struct *pts)
1049{ 1049{
1050 struct si470x_device *radio = video_get_drvdata(video_devdata(file)); 1050 struct si470x_device *radio = video_drvdata(file);
1051 int retval = 0; 1051 int retval = 0;
1052 1052
1053 /* switch on rds reception */ 1053 /* switch on rds reception */
@@ -1071,9 +1071,10 @@ static unsigned int si470x_fops_poll(struct file *file,
1071 */ 1071 */
1072static int si470x_fops_open(struct inode *inode, struct file *file) 1072static int si470x_fops_open(struct inode *inode, struct file *file)
1073{ 1073{
1074 struct si470x_device *radio = video_get_drvdata(video_devdata(file)); 1074 struct si470x_device *radio = video_drvdata(file);
1075 int retval; 1075 int retval;
1076 1076
1077 lock_kernel();
1077 radio->users++; 1078 radio->users++;
1078 1079
1079 retval = usb_autopm_get_interface(radio->intf); 1080 retval = usb_autopm_get_interface(radio->intf);
@@ -1090,6 +1091,7 @@ static int si470x_fops_open(struct inode *inode, struct file *file)
1090 } 1091 }
1091 1092
1092done: 1093done:
1094 unlock_kernel();
1093 return retval; 1095 return retval;
1094} 1096}
1095 1097
@@ -1099,7 +1101,7 @@ done:
1099 */ 1101 */
1100static int si470x_fops_release(struct inode *inode, struct file *file) 1102static int si470x_fops_release(struct inode *inode, struct file *file)
1101{ 1103{
1102 struct si470x_device *radio = video_get_drvdata(video_devdata(file)); 1104 struct si470x_device *radio = video_drvdata(file);
1103 int retval = 0; 1105 int retval = 0;
1104 1106
1105 /* safety check */ 1107 /* safety check */
@@ -1282,7 +1284,7 @@ done:
1282static int si470x_vidioc_g_ctrl(struct file *file, void *priv, 1284static int si470x_vidioc_g_ctrl(struct file *file, void *priv,
1283 struct v4l2_control *ctrl) 1285 struct v4l2_control *ctrl)
1284{ 1286{
1285 struct si470x_device *radio = video_get_drvdata(video_devdata(file)); 1287 struct si470x_device *radio = video_drvdata(file);
1286 int retval = 0; 1288 int retval = 0;
1287 1289
1288 /* safety checks */ 1290 /* safety checks */
@@ -1318,7 +1320,7 @@ done:
1318static int si470x_vidioc_s_ctrl(struct file *file, void *priv, 1320static int si470x_vidioc_s_ctrl(struct file *file, void *priv,
1319 struct v4l2_control *ctrl) 1321 struct v4l2_control *ctrl)
1320{ 1322{
1321 struct si470x_device *radio = video_get_drvdata(video_devdata(file)); 1323 struct si470x_device *radio = video_drvdata(file);
1322 int retval = 0; 1324 int retval = 0;
1323 1325
1324 /* safety checks */ 1326 /* safety checks */
@@ -1405,7 +1407,7 @@ done:
1405static int si470x_vidioc_g_tuner(struct file *file, void *priv, 1407static int si470x_vidioc_g_tuner(struct file *file, void *priv,
1406 struct v4l2_tuner *tuner) 1408 struct v4l2_tuner *tuner)
1407{ 1409{
1408 struct si470x_device *radio = video_get_drvdata(video_devdata(file)); 1410 struct si470x_device *radio = video_drvdata(file);
1409 int retval = 0; 1411 int retval = 0;
1410 1412
1411 /* safety checks */ 1413 /* safety checks */
@@ -1471,7 +1473,7 @@ done:
1471static int si470x_vidioc_s_tuner(struct file *file, void *priv, 1473static int si470x_vidioc_s_tuner(struct file *file, void *priv,
1472 struct v4l2_tuner *tuner) 1474 struct v4l2_tuner *tuner)
1473{ 1475{
1474 struct si470x_device *radio = video_get_drvdata(video_devdata(file)); 1476 struct si470x_device *radio = video_drvdata(file);
1475 int retval = 0; 1477 int retval = 0;
1476 1478
1477 /* safety checks */ 1479 /* safety checks */
@@ -1505,7 +1507,7 @@ done:
1505static int si470x_vidioc_g_frequency(struct file *file, void *priv, 1507static int si470x_vidioc_g_frequency(struct file *file, void *priv,
1506 struct v4l2_frequency *freq) 1508 struct v4l2_frequency *freq)
1507{ 1509{
1508 struct si470x_device *radio = video_get_drvdata(video_devdata(file)); 1510 struct si470x_device *radio = video_drvdata(file);
1509 int retval = 0; 1511 int retval = 0;
1510 1512
1511 /* safety checks */ 1513 /* safety checks */
@@ -1534,7 +1536,7 @@ done:
1534static int si470x_vidioc_s_frequency(struct file *file, void *priv, 1536static int si470x_vidioc_s_frequency(struct file *file, void *priv,
1535 struct v4l2_frequency *freq) 1537 struct v4l2_frequency *freq)
1536{ 1538{
1537 struct si470x_device *radio = video_get_drvdata(video_devdata(file)); 1539 struct si470x_device *radio = video_drvdata(file);
1538 int retval = 0; 1540 int retval = 0;
1539 1541
1540 /* safety checks */ 1542 /* safety checks */
@@ -1563,7 +1565,7 @@ done:
1563static int si470x_vidioc_s_hw_freq_seek(struct file *file, void *priv, 1565static int si470x_vidioc_s_hw_freq_seek(struct file *file, void *priv,
1564 struct v4l2_hw_freq_seek *seek) 1566 struct v4l2_hw_freq_seek *seek)
1565{ 1567{
1566 struct si470x_device *radio = video_get_drvdata(video_devdata(file)); 1568 struct si470x_device *radio = video_drvdata(file);
1567 int retval = 0; 1569 int retval = 0;
1568 1570
1569 /* safety checks */ 1571 /* safety checks */
diff --git a/drivers/media/radio/radio-terratec.c b/drivers/media/radio/radio-terratec.c
index 0876fecc5f27..0abb186a9473 100644
--- a/drivers/media/radio/radio-terratec.c
+++ b/drivers/media/radio/radio-terratec.c
@@ -79,6 +79,7 @@ static spinlock_t lock;
79 79
80struct tt_device 80struct tt_device
81{ 81{
82 unsigned long in_use;
82 int port; 83 int port;
83 int curvol; 84 int curvol;
84 unsigned long curfreq; 85 unsigned long curfreq;
@@ -220,8 +221,7 @@ static int vidioc_querycap(struct file *file, void *priv,
220static int vidioc_g_tuner(struct file *file, void *priv, 221static int vidioc_g_tuner(struct file *file, void *priv,
221 struct v4l2_tuner *v) 222 struct v4l2_tuner *v)
222{ 223{
223 struct video_device *dev = video_devdata(file); 224 struct tt_device *tt = video_drvdata(file);
224 struct tt_device *tt = dev->priv;
225 225
226 if (v->index > 0) 226 if (v->index > 0)
227 return -EINVAL; 227 return -EINVAL;
@@ -248,8 +248,7 @@ static int vidioc_s_tuner(struct file *file, void *priv,
248static int vidioc_s_frequency(struct file *file, void *priv, 248static int vidioc_s_frequency(struct file *file, void *priv,
249 struct v4l2_frequency *f) 249 struct v4l2_frequency *f)
250{ 250{
251 struct video_device *dev = video_devdata(file); 251 struct tt_device *tt = video_drvdata(file);
252 struct tt_device *tt = dev->priv;
253 252
254 tt->curfreq = f->frequency; 253 tt->curfreq = f->frequency;
255 tt_setfreq(tt, tt->curfreq); 254 tt_setfreq(tt, tt->curfreq);
@@ -259,8 +258,7 @@ static int vidioc_s_frequency(struct file *file, void *priv,
259static int vidioc_g_frequency(struct file *file, void *priv, 258static int vidioc_g_frequency(struct file *file, void *priv,
260 struct v4l2_frequency *f) 259 struct v4l2_frequency *f)
261{ 260{
262 struct video_device *dev = video_devdata(file); 261 struct tt_device *tt = video_drvdata(file);
263 struct tt_device *tt = dev->priv;
264 262
265 f->type = V4L2_TUNER_RADIO; 263 f->type = V4L2_TUNER_RADIO;
266 f->frequency = tt->curfreq; 264 f->frequency = tt->curfreq;
@@ -285,8 +283,7 @@ static int vidioc_queryctrl(struct file *file, void *priv,
285static int vidioc_g_ctrl(struct file *file, void *priv, 283static int vidioc_g_ctrl(struct file *file, void *priv,
286 struct v4l2_control *ctrl) 284 struct v4l2_control *ctrl)
287{ 285{
288 struct video_device *dev = video_devdata(file); 286 struct tt_device *tt = video_drvdata(file);
289 struct tt_device *tt = dev->priv;
290 287
291 switch (ctrl->id) { 288 switch (ctrl->id) {
292 case V4L2_CID_AUDIO_MUTE: 289 case V4L2_CID_AUDIO_MUTE:
@@ -305,8 +302,7 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
305static int vidioc_s_ctrl(struct file *file, void *priv, 302static int vidioc_s_ctrl(struct file *file, void *priv,
306 struct v4l2_control *ctrl) 303 struct v4l2_control *ctrl)
307{ 304{
308 struct video_device *dev = video_devdata(file); 305 struct tt_device *tt = video_drvdata(file);
309 struct tt_device *tt = dev->priv;
310 306
311 switch (ctrl->id) { 307 switch (ctrl->id) {
312 case V4L2_CID_AUDIO_MUTE: 308 case V4L2_CID_AUDIO_MUTE:
@@ -356,10 +352,21 @@ static int vidioc_s_audio(struct file *file, void *priv,
356 352
357static struct tt_device terratec_unit; 353static struct tt_device terratec_unit;
358 354
355static int terratec_exclusive_open(struct inode *inode, struct file *file)
356{
357 return test_and_set_bit(0, &terratec_unit.in_use) ? -EBUSY : 0;
358}
359
360static int terratec_exclusive_release(struct inode *inode, struct file *file)
361{
362 clear_bit(0, &terratec_unit.in_use);
363 return 0;
364}
365
359static const struct file_operations terratec_fops = { 366static const struct file_operations terratec_fops = {
360 .owner = THIS_MODULE, 367 .owner = THIS_MODULE,
361 .open = video_exclusive_open, 368 .open = terratec_exclusive_open,
362 .release = video_exclusive_release, 369 .release = terratec_exclusive_release,
363 .ioctl = video_ioctl2, 370 .ioctl = video_ioctl2,
364#ifdef CONFIG_COMPAT 371#ifdef CONFIG_COMPAT
365 .compat_ioctl = v4l_compat_ioctl32, 372 .compat_ioctl = v4l_compat_ioctl32,
@@ -386,6 +393,7 @@ static struct video_device terratec_radio = {
386 .name = "TerraTec ActiveRadio", 393 .name = "TerraTec ActiveRadio",
387 .fops = &terratec_fops, 394 .fops = &terratec_fops,
388 .ioctl_ops = &terratec_ioctl_ops, 395 .ioctl_ops = &terratec_ioctl_ops,
396 .release = video_device_release_empty,
389}; 397};
390 398
391static int __init terratec_init(void) 399static int __init terratec_init(void)
@@ -401,7 +409,7 @@ static int __init terratec_init(void)
401 return -EBUSY; 409 return -EBUSY;
402 } 410 }
403 411
404 terratec_radio.priv=&terratec_unit; 412 video_set_drvdata(&terratec_radio, &terratec_unit);
405 413
406 spin_lock_init(&lock); 414 spin_lock_init(&lock);
407 415
diff --git a/drivers/media/radio/radio-trust.c b/drivers/media/radio/radio-trust.c
index 193161956253..e7b111fcd105 100644
--- a/drivers/media/radio/radio-trust.c
+++ b/drivers/media/radio/radio-trust.c
@@ -78,6 +78,7 @@ static __u16 curtreble;
78static unsigned long curfreq; 78static unsigned long curfreq;
79static int curstereo; 79static int curstereo;
80static int curmute; 80static int curmute;
81static unsigned long in_use;
81 82
82/* i2c addresses */ 83/* i2c addresses */
83#define TDA7318_ADDR 0x88 84#define TDA7318_ADDR 0x88
@@ -336,10 +337,21 @@ static int vidioc_s_audio(struct file *file, void *priv,
336 return 0; 337 return 0;
337} 338}
338 339
340static int trust_exclusive_open(struct inode *inode, struct file *file)
341{
342 return test_and_set_bit(0, &in_use) ? -EBUSY : 0;
343}
344
345static int trust_exclusive_release(struct inode *inode, struct file *file)
346{
347 clear_bit(0, &in_use);
348 return 0;
349}
350
339static const struct file_operations trust_fops = { 351static const struct file_operations trust_fops = {
340 .owner = THIS_MODULE, 352 .owner = THIS_MODULE,
341 .open = video_exclusive_open, 353 .open = trust_exclusive_open,
342 .release = video_exclusive_release, 354 .release = trust_exclusive_release,
343 .ioctl = video_ioctl2, 355 .ioctl = video_ioctl2,
344#ifdef CONFIG_COMPAT 356#ifdef CONFIG_COMPAT
345 .compat_ioctl = v4l_compat_ioctl32, 357 .compat_ioctl = v4l_compat_ioctl32,
@@ -366,6 +378,7 @@ static struct video_device trust_radio = {
366 .name = "Trust FM Radio", 378 .name = "Trust FM Radio",
367 .fops = &trust_fops, 379 .fops = &trust_fops,
368 .ioctl_ops = &trust_ioctl_ops, 380 .ioctl_ops = &trust_ioctl_ops,
381 .release = video_device_release_empty,
369}; 382};
370 383
371static int __init trust_init(void) 384static int __init trust_init(void)
diff --git a/drivers/media/radio/radio-typhoon.c b/drivers/media/radio/radio-typhoon.c
index f8d62cfea774..952ec35a8415 100644
--- a/drivers/media/radio/radio-typhoon.c
+++ b/drivers/media/radio/radio-typhoon.c
@@ -79,7 +79,7 @@ static struct v4l2_queryctrl radio_qctrl[] = {
79#endif 79#endif
80 80
81struct typhoon_device { 81struct typhoon_device {
82 int users; 82 unsigned long in_use;
83 int iobase; 83 int iobase;
84 int curvol; 84 int curvol;
85 int muted; 85 int muted;
@@ -223,8 +223,7 @@ static int vidioc_s_tuner(struct file *file, void *priv,
223static int vidioc_s_frequency(struct file *file, void *priv, 223static int vidioc_s_frequency(struct file *file, void *priv,
224 struct v4l2_frequency *f) 224 struct v4l2_frequency *f)
225{ 225{
226 struct video_device *dev = video_devdata(file); 226 struct typhoon_device *typhoon = video_drvdata(file);
227 struct typhoon_device *typhoon = dev->priv;
228 227
229 typhoon->curfreq = f->frequency; 228 typhoon->curfreq = f->frequency;
230 typhoon_setfreq(typhoon, typhoon->curfreq); 229 typhoon_setfreq(typhoon, typhoon->curfreq);
@@ -234,8 +233,7 @@ static int vidioc_s_frequency(struct file *file, void *priv,
234static int vidioc_g_frequency(struct file *file, void *priv, 233static int vidioc_g_frequency(struct file *file, void *priv,
235 struct v4l2_frequency *f) 234 struct v4l2_frequency *f)
236{ 235{
237 struct video_device *dev = video_devdata(file); 236 struct typhoon_device *typhoon = video_drvdata(file);
238 struct typhoon_device *typhoon = dev->priv;
239 237
240 f->type = V4L2_TUNER_RADIO; 238 f->type = V4L2_TUNER_RADIO;
241 f->frequency = typhoon->curfreq; 239 f->frequency = typhoon->curfreq;
@@ -261,8 +259,7 @@ static int vidioc_queryctrl(struct file *file, void *priv,
261static int vidioc_g_ctrl(struct file *file, void *priv, 259static int vidioc_g_ctrl(struct file *file, void *priv,
262 struct v4l2_control *ctrl) 260 struct v4l2_control *ctrl)
263{ 261{
264 struct video_device *dev = video_devdata(file); 262 struct typhoon_device *typhoon = video_drvdata(file);
265 struct typhoon_device *typhoon = dev->priv;
266 263
267 switch (ctrl->id) { 264 switch (ctrl->id) {
268 case V4L2_CID_AUDIO_MUTE: 265 case V4L2_CID_AUDIO_MUTE:
@@ -278,8 +275,7 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
278static int vidioc_s_ctrl (struct file *file, void *priv, 275static int vidioc_s_ctrl (struct file *file, void *priv,
279 struct v4l2_control *ctrl) 276 struct v4l2_control *ctrl)
280{ 277{
281 struct video_device *dev = video_devdata(file); 278 struct typhoon_device *typhoon = video_drvdata(file);
282 struct typhoon_device *typhoon = dev->priv;
283 279
284 switch (ctrl->id) { 280 switch (ctrl->id) {
285 case V4L2_CID_AUDIO_MUTE: 281 case V4L2_CID_AUDIO_MUTE:
@@ -334,10 +330,21 @@ static struct typhoon_device typhoon_unit =
334 .mutefreq = CONFIG_RADIO_TYPHOON_MUTEFREQ, 330 .mutefreq = CONFIG_RADIO_TYPHOON_MUTEFREQ,
335}; 331};
336 332
333static int typhoon_exclusive_open(struct inode *inode, struct file *file)
334{
335 return test_and_set_bit(0, &typhoon_unit.in_use) ? -EBUSY : 0;
336}
337
338static int typhoon_exclusive_release(struct inode *inode, struct file *file)
339{
340 clear_bit(0, &typhoon_unit.in_use);
341 return 0;
342}
343
337static const struct file_operations typhoon_fops = { 344static const struct file_operations typhoon_fops = {
338 .owner = THIS_MODULE, 345 .owner = THIS_MODULE,
339 .open = video_exclusive_open, 346 .open = typhoon_exclusive_open,
340 .release = video_exclusive_release, 347 .release = typhoon_exclusive_release,
341 .ioctl = video_ioctl2, 348 .ioctl = video_ioctl2,
342#ifdef CONFIG_COMPAT 349#ifdef CONFIG_COMPAT
343 .compat_ioctl = v4l_compat_ioctl32, 350 .compat_ioctl = v4l_compat_ioctl32,
@@ -364,6 +371,7 @@ static struct video_device typhoon_radio = {
364 .name = "Typhoon Radio", 371 .name = "Typhoon Radio",
365 .fops = &typhoon_fops, 372 .fops = &typhoon_fops,
366 .ioctl_ops = &typhoon_ioctl_ops, 373 .ioctl_ops = &typhoon_ioctl_ops,
374 .release = video_device_release_empty,
367}; 375};
368 376
369#ifdef CONFIG_RADIO_TYPHOON_PROC_FS 377#ifdef CONFIG_RADIO_TYPHOON_PROC_FS
@@ -446,9 +454,8 @@ static int __init typhoon_init(void)
446 return -EBUSY; 454 return -EBUSY;
447 } 455 }
448 456
449 typhoon_radio.priv = &typhoon_unit; 457 video_set_drvdata(&typhoon_radio, &typhoon_unit);
450 if (video_register_device(&typhoon_radio, VFL_TYPE_RADIO, radio_nr) == -1) 458 if (video_register_device(&typhoon_radio, VFL_TYPE_RADIO, radio_nr) < 0) {
451 {
452 release_region(io, 8); 459 release_region(io, 8);
453 return -EINVAL; 460 return -EINVAL;
454 } 461 }
diff --git a/drivers/media/radio/radio-zoltrix.c b/drivers/media/radio/radio-zoltrix.c
index 51d57ed3b3e1..15b10bad6796 100644
--- a/drivers/media/radio/radio-zoltrix.c
+++ b/drivers/media/radio/radio-zoltrix.c
@@ -69,6 +69,7 @@ static int io = CONFIG_RADIO_ZOLTRIX_PORT;
69static int radio_nr = -1; 69static int radio_nr = -1;
70 70
71struct zol_device { 71struct zol_device {
72 unsigned long in_use;
72 int port; 73 int port;
73 int curvol; 74 int curvol;
74 unsigned long curfreq; 75 unsigned long curfreq;
@@ -122,8 +123,11 @@ static int zol_setfreq(struct zol_device *dev, unsigned long freq)
122 unsigned int stereo = dev->stereo; 123 unsigned int stereo = dev->stereo;
123 int i; 124 int i;
124 125
125 if (freq == 0) 126 if (freq == 0) {
126 return 1; 127 printk(KERN_WARNING "zoltrix: received zero freq. Failed to set.\n");
128 return -EINVAL;
129 }
130
127 m = (freq / 160 - 8800) * 2; 131 m = (freq / 160 - 8800) * 2;
128 f = (unsigned long long) m + 0x4d1c; 132 f = (unsigned long long) m + 0x4d1c;
129 133
@@ -245,8 +249,7 @@ static int vidioc_querycap(struct file *file, void *priv,
245static int vidioc_g_tuner(struct file *file, void *priv, 249static int vidioc_g_tuner(struct file *file, void *priv,
246 struct v4l2_tuner *v) 250 struct v4l2_tuner *v)
247{ 251{
248 struct video_device *dev = video_devdata(file); 252 struct zol_device *zol = video_drvdata(file);
249 struct zol_device *zol = dev->priv;
250 253
251 if (v->index > 0) 254 if (v->index > 0)
252 return -EINVAL; 255 return -EINVAL;
@@ -276,19 +279,20 @@ static int vidioc_s_tuner(struct file *file, void *priv,
276static int vidioc_s_frequency(struct file *file, void *priv, 279static int vidioc_s_frequency(struct file *file, void *priv,
277 struct v4l2_frequency *f) 280 struct v4l2_frequency *f)
278{ 281{
279 struct video_device *dev = video_devdata(file); 282 struct zol_device *zol = video_drvdata(file);
280 struct zol_device *zol = dev->priv;
281 283
282 zol->curfreq = f->frequency; 284 zol->curfreq = f->frequency;
283 zol_setfreq(zol, zol->curfreq); 285 if (zol_setfreq(zol, zol->curfreq) != 0) {
286 printk(KERN_WARNING "zoltrix: Set frequency failed.\n");
287 return -EINVAL;
288 }
284 return 0; 289 return 0;
285} 290}
286 291
287static int vidioc_g_frequency(struct file *file, void *priv, 292static int vidioc_g_frequency(struct file *file, void *priv,
288 struct v4l2_frequency *f) 293 struct v4l2_frequency *f)
289{ 294{
290 struct video_device *dev = video_devdata(file); 295 struct zol_device *zol = video_drvdata(file);
291 struct zol_device *zol = dev->priv;
292 296
293 f->type = V4L2_TUNER_RADIO; 297 f->type = V4L2_TUNER_RADIO;
294 f->frequency = zol->curfreq; 298 f->frequency = zol->curfreq;
@@ -313,8 +317,7 @@ static int vidioc_queryctrl(struct file *file, void *priv,
313static int vidioc_g_ctrl(struct file *file, void *priv, 317static int vidioc_g_ctrl(struct file *file, void *priv,
314 struct v4l2_control *ctrl) 318 struct v4l2_control *ctrl)
315{ 319{
316 struct video_device *dev = video_devdata(file); 320 struct zol_device *zol = video_drvdata(file);
317 struct zol_device *zol = dev->priv;
318 321
319 switch (ctrl->id) { 322 switch (ctrl->id) {
320 case V4L2_CID_AUDIO_MUTE: 323 case V4L2_CID_AUDIO_MUTE:
@@ -330,8 +333,7 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
330static int vidioc_s_ctrl(struct file *file, void *priv, 333static int vidioc_s_ctrl(struct file *file, void *priv,
331 struct v4l2_control *ctrl) 334 struct v4l2_control *ctrl)
332{ 335{
333 struct video_device *dev = video_devdata(file); 336 struct zol_device *zol = video_drvdata(file);
334 struct zol_device *zol = dev->priv;
335 337
336 switch (ctrl->id) { 338 switch (ctrl->id) {
337 case V4L2_CID_AUDIO_MUTE: 339 case V4L2_CID_AUDIO_MUTE:
@@ -347,7 +349,10 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
347 return 0; 349 return 0;
348 } 350 }
349 zol->stereo = 1; 351 zol->stereo = 1;
350 zol_setfreq(zol, zol->curfreq); 352 if (zol_setfreq(zol, zol->curfreq) != 0) {
353 printk(KERN_WARNING "zoltrix: Set frequency failed.\n");
354 return -EINVAL;
355 }
351#if 0 356#if 0
352/* FIXME: Implement stereo/mono switch on V4L2 */ 357/* FIXME: Implement stereo/mono switch on V4L2 */
353 if (v->mode & VIDEO_SOUND_STEREO) { 358 if (v->mode & VIDEO_SOUND_STEREO) {
@@ -396,11 +401,22 @@ static int vidioc_s_audio(struct file *file, void *priv,
396 401
397static struct zol_device zoltrix_unit; 402static struct zol_device zoltrix_unit;
398 403
404static int zoltrix_exclusive_open(struct inode *inode, struct file *file)
405{
406 return test_and_set_bit(0, &zoltrix_unit.in_use) ? -EBUSY : 0;
407}
408
409static int zoltrix_exclusive_release(struct inode *inode, struct file *file)
410{
411 clear_bit(0, &zoltrix_unit.in_use);
412 return 0;
413}
414
399static const struct file_operations zoltrix_fops = 415static const struct file_operations zoltrix_fops =
400{ 416{
401 .owner = THIS_MODULE, 417 .owner = THIS_MODULE,
402 .open = video_exclusive_open, 418 .open = zoltrix_exclusive_open,
403 .release = video_exclusive_release, 419 .release = zoltrix_exclusive_release,
404 .ioctl = video_ioctl2, 420 .ioctl = video_ioctl2,
405#ifdef CONFIG_COMPAT 421#ifdef CONFIG_COMPAT
406 .compat_ioctl = v4l_compat_ioctl32, 422 .compat_ioctl = v4l_compat_ioctl32,
@@ -427,6 +443,7 @@ static struct video_device zoltrix_radio = {
427 .name = "Zoltrix Radio Plus", 443 .name = "Zoltrix Radio Plus",
428 .fops = &zoltrix_fops, 444 .fops = &zoltrix_fops,
429 .ioctl_ops = &zoltrix_ioctl_ops, 445 .ioctl_ops = &zoltrix_ioctl_ops,
446 .release = video_device_release_empty,
430}; 447};
431 448
432static int __init zoltrix_init(void) 449static int __init zoltrix_init(void)
@@ -440,7 +457,7 @@ static int __init zoltrix_init(void)
440 return -ENXIO; 457 return -ENXIO;
441 } 458 }
442 459
443 zoltrix_radio.priv = &zoltrix_unit; 460 video_set_drvdata(&zoltrix_radio, &zoltrix_unit);
444 if (!request_region(io, 2, "zoltrix")) { 461 if (!request_region(io, 2, "zoltrix")) {
445 printk(KERN_ERR "zoltrix: port 0x%x already in use\n", io); 462 printk(KERN_ERR "zoltrix: port 0x%x already in use\n", io);
446 return -EBUSY; 463 return -EBUSY;