diff options
Diffstat (limited to 'drivers/media/radio')
-rw-r--r-- | drivers/media/radio/Kconfig | 12 | ||||
-rw-r--r-- | drivers/media/radio/Makefile | 1 | ||||
-rw-r--r-- | drivers/media/radio/dsbr100.c | 28 | ||||
-rw-r--r-- | drivers/media/radio/radio-aimslab.c | 34 | ||||
-rw-r--r-- | drivers/media/radio/radio-aztech.c | 40 | ||||
-rw-r--r-- | drivers/media/radio/radio-cadet.c | 1 | ||||
-rw-r--r-- | drivers/media/radio/radio-gemtek-pci.c | 42 | ||||
-rw-r--r-- | drivers/media/radio/radio-gemtek.c | 37 | ||||
-rw-r--r-- | drivers/media/radio/radio-maestro.c | 34 | ||||
-rw-r--r-- | drivers/media/radio/radio-maxiradio.c | 40 | ||||
-rw-r--r-- | drivers/media/radio/radio-mr800.c | 628 | ||||
-rw-r--r-- | drivers/media/radio/radio-rtrack2.c | 34 | ||||
-rw-r--r-- | drivers/media/radio/radio-sf16fmi.c | 34 | ||||
-rw-r--r-- | drivers/media/radio/radio-sf16fmr2.c | 34 | ||||
-rw-r--r-- | drivers/media/radio/radio-si470x.c | 24 | ||||
-rw-r--r-- | drivers/media/radio/radio-terratec.c | 34 | ||||
-rw-r--r-- | drivers/media/radio/radio-trust.c | 17 | ||||
-rw-r--r-- | drivers/media/radio/radio-typhoon.c | 35 | ||||
-rw-r--r-- | drivers/media/radio/radio-zoltrix.c | 51 |
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 | ||
364 | config 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 | |||
364 | endif # RADIO_ADAPTERS | 376 | endif # 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 | |||
18 | obj-$(CONFIG_RADIO_MAESTRO) += radio-maestro.o | 18 | obj-$(CONFIG_RADIO_MAESTRO) += radio-maestro.o |
19 | obj-$(CONFIG_USB_DSBR) += dsbr100.o | 19 | obj-$(CONFIG_USB_DSBR) += dsbr100.o |
20 | obj-$(CONFIG_USB_SI470X) += radio-si470x.o | 20 | obj-$(CONFIG_USB_SI470X) += radio-si470x.o |
21 | obj-$(CONFIG_USB_MR800) += radio-mr800.o | ||
21 | 22 | ||
22 | EXTRA_CFLAGS += -Isound | 23 | EXTRA_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, | |||
274 | static int vidioc_g_tuner(struct file *file, void *priv, | 274 | static 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, | |||
306 | static int vidioc_s_frequency(struct file *file, void *priv, | 306 | static 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, | |||
317 | static int vidioc_g_frequency(struct file *file, void *priv, | 317 | static 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, | |||
342 | static int vidioc_g_ctrl(struct file *file, void *priv, | 342 | static 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, | |||
355 | static int vidioc_s_ctrl(struct file *file, void *priv, | 355 | static 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 | ||
406 | static int usb_dsbr100_open(struct inode *inode, struct file *file) | 410 | static 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 | ||
422 | static int usb_dsbr100_close(struct inode *inode, struct file *file) | 429 | static 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, | |||
507 | static int __init dsbr100_init(void) | 514 | static 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 | ||
52 | struct rt_device | 52 | struct 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, | |||
245 | static int vidioc_g_tuner(struct file *file, void *priv, | 246 | static 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, | |||
273 | static int vidioc_s_frequency(struct file *file, void *priv, | 273 | static 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, | |||
284 | static int vidioc_g_frequency(struct file *file, void *priv, | 283 | static 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, | |||
310 | static int vidioc_g_ctrl(struct file *file, void *priv, | 308 | static 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, | |||
327 | static int vidioc_s_ctrl(struct file *file, void *priv, | 324 | static 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 | ||
379 | static struct rt_device rtrack_unit; | 375 | static struct rt_device rtrack_unit; |
380 | 376 | ||
377 | static 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 | |||
382 | static int rtrack_exclusive_release(struct inode *inode, struct file *file) | ||
383 | { | ||
384 | clear_bit(0, &rtrack_unit.in_use); | ||
385 | return 0; | ||
386 | } | ||
387 | |||
381 | static const struct file_operations rtrack_fops = { | 388 | static 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 | ||
413 | static int __init rtrack_init(void) | 421 | static 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 | ||
71 | struct az_device | 71 | struct 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, | |||
195 | static int vidioc_g_tuner (struct file *file, void *priv, | 196 | static 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, | |||
264 | static int vidioc_s_frequency (struct file *file, void *priv, | 264 | static 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, | |||
275 | static int vidioc_g_frequency (struct file *file, void *priv, | 274 | static 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, | |||
302 | static int vidioc_g_ctrl (struct file *file, void *priv, | 300 | static 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, | |||
322 | static int vidioc_s_ctrl (struct file *file, void *priv, | 319 | static 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 | ||
343 | static struct az_device aztech_unit; | 339 | static struct az_device aztech_unit; |
344 | 340 | ||
341 | static 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 | |||
346 | static int aztech_exclusive_release(struct inode *inode, struct file *file) | ||
347 | { | ||
348 | clear_bit(0, &aztech_unit.in_use); | ||
349 | return 0; | ||
350 | } | ||
351 | |||
345 | static const struct file_operations aztech_fops = { | 352 | static 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 | ||
371 | static struct video_device aztech_radio = { | 378 | static 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 | ||
377 | module_param_named(debug,aztech_radio.debug, int, 0644); | 385 | module_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 | ||
103 | static const char rcsid[] = "$Id: radio-gemtek-pci.c,v 1.1 2001/07/23 08:08:16 ted Exp ted $"; | ||
104 | |||
105 | static int nr_radio = -1; | 103 | static int nr_radio = -1; |
104 | static unsigned long in_use; | ||
106 | 105 | ||
107 | static inline u8 gemtek_pci_out( u16 value, u32 port ) | 106 | static inline u8 gemtek_pci_out( u16 value, u32 port ) |
108 | { | 107 | { |
@@ -205,8 +204,7 @@ static int vidioc_querycap(struct file *file, void *priv, | |||
205 | static int vidioc_g_tuner(struct file *file, void *priv, | 204 | static 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, | |||
233 | static int vidioc_s_frequency(struct file *file, void *priv, | 231 | static 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, | |||
248 | static int vidioc_g_frequency(struct file *file, void *priv, | 245 | static 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, | |||
273 | static int vidioc_g_ctrl(struct file *file, void *priv, | 269 | static 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, | |||
293 | static int vidioc_s_ctrl(struct file *file, void *priv, | 288 | static 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 | ||
365 | static int mx = 1; | 359 | static int mx = 1; |
366 | 360 | ||
361 | static 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 | |||
366 | static int gemtek_pci_exclusive_release(struct inode *inode, struct file *file) | ||
367 | { | ||
368 | clear_bit(0, &in_use); | ||
369 | return 0; | ||
370 | } | ||
371 | |||
367 | static const struct file_operations gemtek_pci_fops = { | 372 | static 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 | ||
393 | static struct video_device vdev_template = { | 398 | static 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 | ||
399 | static int __devinit gemtek_pci_probe( struct pci_dev *pci_dev, const struct pci_device_id *pci_id ) | 405 | static 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; | |||
57 | static int keepmuted = 1; | 57 | static int keepmuted = 1; |
58 | static int initmute = 1; | 58 | static int initmute = 1; |
59 | static int radio_nr = -1; | 59 | static int radio_nr = -1; |
60 | static unsigned long in_use; | ||
60 | 61 | ||
61 | module_param(io, int, 0444); | 62 | module_param(io, int, 0444); |
62 | MODULE_PARM_DESC(io, "Force I/O port for the GemTek Radio card if automatic " | 63 | MODULE_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 | ||
397 | static int gemtek_exclusive_open(struct inode *inode, struct file *file) | ||
398 | { | ||
399 | return test_and_set_bit(0, &in_use) ? -EBUSY : 0; | ||
400 | } | ||
401 | |||
402 | static int gemtek_exclusive_release(struct inode *inode, struct file *file) | ||
403 | { | ||
404 | clear_bit(0, &in_use); | ||
405 | return 0; | ||
406 | } | ||
407 | |||
396 | static const struct file_operations gemtek_fops = { | 408 | static 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) | |||
447 | static int vidioc_s_frequency(struct file *file, void *priv, | 459 | static 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, | |||
458 | static int vidioc_g_frequency(struct file *file, void *priv, | 469 | static 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, | |||
483 | static int vidioc_g_ctrl(struct file *file, void *priv, | 493 | static 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, | |||
503 | static int vidioc_s_ctrl(struct file *file, void *priv, | 512 | static 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 | ||
571 | static struct video_device gemtek_radio = { | 579 | static 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[] = { | |||
75 | static int radio_nr = -1; | 75 | static int radio_nr = -1; |
76 | module_param(radio_nr, int, 0); | 76 | module_param(radio_nr, int, 0); |
77 | 77 | ||
78 | static unsigned long in_use; | ||
79 | |||
78 | static int maestro_probe(struct pci_dev *pdev, const struct pci_device_id *ent); | 80 | static int maestro_probe(struct pci_dev *pdev, const struct pci_device_id *ent); |
81 | |||
82 | static int maestro_exclusive_open(struct inode *inode, struct file *file) | ||
83 | { | ||
84 | return test_and_set_bit(0, &in_use) ? -EBUSY : 0; | ||
85 | } | ||
86 | |||
87 | static int maestro_exclusive_release(struct inode *inode, struct file *file) | ||
88 | { | ||
89 | clear_bit(0, &in_use); | ||
90 | return 0; | ||
91 | } | ||
92 | |||
79 | static void maestro_remove(struct pci_dev *pdev); | 93 | static void maestro_remove(struct pci_dev *pdev); |
80 | 94 | ||
81 | static struct pci_device_id maestro_r_pci_tbl[] = { | 95 | static struct pci_device_id maestro_r_pci_tbl[] = { |
@@ -98,8 +112,8 @@ static struct pci_driver maestro_r_driver = { | |||
98 | 112 | ||
99 | static const struct file_operations maestro_fops = { | 113 | static 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, | |||
196 | static int vidioc_g_tuner(struct file *file, void *priv, | 210 | static 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, | |||
229 | static int vidioc_s_frequency(struct file *file, void *priv, | 242 | static 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, | |||
241 | static int vidioc_g_frequency(struct file *file, void *priv, | 253 | static 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, | |||
267 | static int vidioc_g_ctrl(struct file *file, void *priv, | 278 | static 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, | |||
281 | static int vidioc_s_ctrl(struct file *file, void *priv, | 291 | static 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 | ||
379 | static int __devinit maestro_probe(struct pci_dev *pdev, | 389 | static 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 ; | |||
85 | static int radio_nr = -1; | 85 | static int radio_nr = -1; |
86 | module_param(radio_nr, int, 0); | 86 | module_param(radio_nr, int, 0); |
87 | 87 | ||
88 | static 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 | ||
103 | static int maxiradio_exclusive_open(struct inode *inode, struct file *file) | ||
104 | { | ||
105 | return test_and_set_bit(0, &in_use) ? -EBUSY : 0; | ||
106 | } | ||
107 | |||
108 | static int maxiradio_exclusive_release(struct inode *inode, struct file *file) | ||
109 | { | ||
110 | clear_bit(0, &in_use); | ||
111 | return 0; | ||
112 | } | ||
113 | |||
102 | static const struct file_operations maxiradio_fops = { | 114 | static 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, | |||
219 | static int vidioc_g_tuner (struct file *file, void *priv, | 231 | static 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, | |||
290 | static int vidioc_s_frequency (struct file *file, void *priv, | 301 | static 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, | |||
312 | static int vidioc_g_frequency (struct file *file, void *priv, | 322 | static 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, | |||
343 | static int vidioc_g_ctrl (struct file *file, void *priv, | 352 | static 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, | |||
358 | static int vidioc_s_ctrl (struct file *file, void *priv, | 366 | static 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 | ||
392 | static struct video_device maxiradio_radio = { | 399 | static 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 | ||
398 | static int __devinit maxiradio_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | 406 | static 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 | |||
68 | MODULE_AUTHOR(DRIVER_AUTHOR); | ||
69 | MODULE_DESCRIPTION(DRIVER_DESC); | ||
70 | MODULE_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 | ||
80 | devices, 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 */ | ||
86 | static int radio_nr = -1; | ||
87 | module_param(radio_nr, int, 0); | ||
88 | MODULE_PARM_DESC(radio_nr, "Radio Nr"); | ||
89 | |||
90 | static 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 | |||
122 | static int usb_amradio_probe(struct usb_interface *intf, | ||
123 | const struct usb_device_id *id); | ||
124 | static void usb_amradio_disconnect(struct usb_interface *intf); | ||
125 | static int usb_amradio_open(struct inode *inode, struct file *file); | ||
126 | static int usb_amradio_close(struct inode *inode, struct file *file); | ||
127 | static int usb_amradio_suspend(struct usb_interface *intf, | ||
128 | pm_message_t message); | ||
129 | static int usb_amradio_resume(struct usb_interface *intf); | ||
130 | |||
131 | /* Data for one (physical) device */ | ||
132 | struct 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 */ | ||
147 | static 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 | |||
153 | MODULE_DEVICE_TABLE(usb, usb_amradio_device_table); | ||
154 | |||
155 | /* USB subsystem interface */ | ||
156 | static 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. */ | ||
168 | static 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 */ | ||
200 | static 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 */ | ||
232 | static 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 | ||
284 | if nothing keeps us from doing it. If something is still | ||
285 | keeping us busy, the release callback of v4l will take care | ||
286 | of releasing it. */ | ||
287 | static 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 */ | ||
306 | static 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 */ | ||
318 | static 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 */ | ||
346 | static 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 */ | ||
355 | static 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 */ | ||
367 | static 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 */ | ||
378 | static 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 */ | ||
394 | static 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 */ | ||
408 | static 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 */ | ||
432 | static 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 */ | ||
444 | static 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 */ | ||
453 | static 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 */ | ||
460 | static 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() */ | ||
468 | static 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 */ | ||
486 | static 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 */ | ||
501 | static 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 */ | ||
514 | static 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 */ | ||
527 | static 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 | |||
538 | static 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 */ | ||
554 | static 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 | ||
562 | usb if it is */ | ||
563 | static 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 | |||
611 | static 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 | |||
621 | static void __exit amradio_exit(void) | ||
622 | { | ||
623 | usb_deregister(&usb_amradio_driver); | ||
624 | } | ||
625 | |||
626 | module_init(amradio_init); | ||
627 | module_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 | ||
53 | struct rt_device | 53 | struct 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) | |||
153 | static int vidioc_g_tuner(struct file *file, void *priv, | 154 | static 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, | |||
173 | static int vidioc_s_frequency(struct file *file, void *priv, | 173 | static 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, | |||
184 | static int vidioc_g_frequency(struct file *file, void *priv, | 183 | static 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, | |||
210 | static int vidioc_g_ctrl(struct file *file, void *priv, | 208 | static 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, | |||
230 | static int vidioc_s_ctrl(struct file *file, void *priv, | 227 | static 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 | ||
285 | static struct rt_device rtrack2_unit; | 281 | static struct rt_device rtrack2_unit; |
286 | 282 | ||
283 | static 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 | |||
288 | static int rtrack2_exclusive_release(struct inode *inode, struct file *file) | ||
289 | { | ||
290 | clear_bit(0, &rtrack2_unit.in_use); | ||
291 | return 0; | ||
292 | } | ||
293 | |||
287 | static const struct file_operations rtrack2_fops = { | 294 | static 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 | ||
319 | static int __init rtrack2_init(void) | 327 | static 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 | ||
46 | struct fmi_device | 46 | struct 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, | |||
175 | static int vidioc_s_frequency(struct file *file, void *priv, | 175 | static 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, | |||
193 | static int vidioc_g_frequency(struct file *file, void *priv, | 192 | static 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, | |||
221 | static int vidioc_g_ctrl(struct file *file, void *priv, | 219 | static 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, | |||
235 | static int vidioc_s_ctrl(struct file *file, void *priv, | 232 | static 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 | ||
285 | static struct fmi_device fmi_unit; | 281 | static struct fmi_device fmi_unit; |
286 | 282 | ||
283 | static 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 | |||
288 | static int fmi_exclusive_release(struct inode *inode, struct file *file) | ||
289 | { | ||
290 | clear_bit(0, &fmi_unit.in_use); | ||
291 | return 0; | ||
292 | } | ||
293 | |||
287 | static const struct file_operations fmi_fops = { | 294 | static 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 */ |
65 | struct fmr2_device | 65 | struct 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, | |||
262 | static int vidioc_s_frequency(struct file *file, void *priv, | 262 | static 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, | |||
286 | static int vidioc_g_frequency(struct file *file, void *priv, | 285 | static 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, | |||
313 | static int vidioc_g_ctrl(struct file *file, void *priv, | 311 | static 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, | |||
330 | static int vidioc_s_ctrl(struct file *file, void *priv, | 327 | static 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 | ||
401 | static struct fmr2_device fmr2_unit; | 397 | static struct fmr2_device fmr2_unit; |
402 | 398 | ||
399 | static 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 | |||
404 | static int fmr2_exclusive_release(struct inode *inode, struct file *file) | ||
405 | { | ||
406 | clear_bit(0, &fmr2_unit.in_use); | ||
407 | return 0; | ||
408 | } | ||
409 | |||
403 | static const struct file_operations fmr2_fops = { | 410 | static 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 | ||
435 | static int __init fmr2_init(void) | 443 | static 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) | |||
986 | static ssize_t si470x_fops_read(struct file *file, char __user *buf, | 986 | static 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: | |||
1047 | static unsigned int si470x_fops_poll(struct file *file, | 1047 | static 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 | */ |
1072 | static int si470x_fops_open(struct inode *inode, struct file *file) | 1072 | static 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 | ||
1092 | done: | 1093 | done: |
1094 | unlock_kernel(); | ||
1093 | return retval; | 1095 | return retval; |
1094 | } | 1096 | } |
1095 | 1097 | ||
@@ -1099,7 +1101,7 @@ done: | |||
1099 | */ | 1101 | */ |
1100 | static int si470x_fops_release(struct inode *inode, struct file *file) | 1102 | static 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: | |||
1282 | static int si470x_vidioc_g_ctrl(struct file *file, void *priv, | 1284 | static 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: | |||
1318 | static int si470x_vidioc_s_ctrl(struct file *file, void *priv, | 1320 | static 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: | |||
1405 | static int si470x_vidioc_g_tuner(struct file *file, void *priv, | 1407 | static 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: | |||
1471 | static int si470x_vidioc_s_tuner(struct file *file, void *priv, | 1473 | static 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: | |||
1505 | static int si470x_vidioc_g_frequency(struct file *file, void *priv, | 1507 | static 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: | |||
1534 | static int si470x_vidioc_s_frequency(struct file *file, void *priv, | 1536 | static 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: | |||
1563 | static int si470x_vidioc_s_hw_freq_seek(struct file *file, void *priv, | 1565 | static 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 | ||
80 | struct tt_device | 80 | struct 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, | |||
220 | static int vidioc_g_tuner(struct file *file, void *priv, | 221 | static 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, | |||
248 | static int vidioc_s_frequency(struct file *file, void *priv, | 248 | static 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, | |||
259 | static int vidioc_g_frequency(struct file *file, void *priv, | 258 | static 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, | |||
285 | static int vidioc_g_ctrl(struct file *file, void *priv, | 283 | static 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, | |||
305 | static int vidioc_s_ctrl(struct file *file, void *priv, | 302 | static 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 | ||
357 | static struct tt_device terratec_unit; | 353 | static struct tt_device terratec_unit; |
358 | 354 | ||
355 | static 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 | |||
360 | static int terratec_exclusive_release(struct inode *inode, struct file *file) | ||
361 | { | ||
362 | clear_bit(0, &terratec_unit.in_use); | ||
363 | return 0; | ||
364 | } | ||
365 | |||
359 | static const struct file_operations terratec_fops = { | 366 | static 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 | ||
391 | static int __init terratec_init(void) | 399 | static 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; | |||
78 | static unsigned long curfreq; | 78 | static unsigned long curfreq; |
79 | static int curstereo; | 79 | static int curstereo; |
80 | static int curmute; | 80 | static int curmute; |
81 | static 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 | ||
340 | static int trust_exclusive_open(struct inode *inode, struct file *file) | ||
341 | { | ||
342 | return test_and_set_bit(0, &in_use) ? -EBUSY : 0; | ||
343 | } | ||
344 | |||
345 | static int trust_exclusive_release(struct inode *inode, struct file *file) | ||
346 | { | ||
347 | clear_bit(0, &in_use); | ||
348 | return 0; | ||
349 | } | ||
350 | |||
339 | static const struct file_operations trust_fops = { | 351 | static 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 | ||
371 | static int __init trust_init(void) | 384 | static 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 | ||
81 | struct typhoon_device { | 81 | struct 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, | |||
223 | static int vidioc_s_frequency(struct file *file, void *priv, | 223 | static 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, | |||
234 | static int vidioc_g_frequency(struct file *file, void *priv, | 233 | static 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, | |||
261 | static int vidioc_g_ctrl(struct file *file, void *priv, | 259 | static 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, | |||
278 | static int vidioc_s_ctrl (struct file *file, void *priv, | 275 | static 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 | ||
333 | static 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 | |||
338 | static int typhoon_exclusive_release(struct inode *inode, struct file *file) | ||
339 | { | ||
340 | clear_bit(0, &typhoon_unit.in_use); | ||
341 | return 0; | ||
342 | } | ||
343 | |||
337 | static const struct file_operations typhoon_fops = { | 344 | static 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; | |||
69 | static int radio_nr = -1; | 69 | static int radio_nr = -1; |
70 | 70 | ||
71 | struct zol_device { | 71 | struct 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, | |||
245 | static int vidioc_g_tuner(struct file *file, void *priv, | 249 | static 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, | |||
276 | static int vidioc_s_frequency(struct file *file, void *priv, | 279 | static 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 | ||
287 | static int vidioc_g_frequency(struct file *file, void *priv, | 292 | static 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, | |||
313 | static int vidioc_g_ctrl(struct file *file, void *priv, | 317 | static 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, | |||
330 | static int vidioc_s_ctrl(struct file *file, void *priv, | 333 | static 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 | ||
397 | static struct zol_device zoltrix_unit; | 402 | static struct zol_device zoltrix_unit; |
398 | 403 | ||
404 | static 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 | |||
409 | static int zoltrix_exclusive_release(struct inode *inode, struct file *file) | ||
410 | { | ||
411 | clear_bit(0, &zoltrix_unit.in_use); | ||
412 | return 0; | ||
413 | } | ||
414 | |||
399 | static const struct file_operations zoltrix_fops = | 415 | static 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 | ||
432 | static int __init zoltrix_init(void) | 449 | static 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; |