diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-05-11 15:57:16 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-05-11 15:57:16 -0400 |
commit | 57a44415beee38d1afcd8e1b5fad66f3414d2dac (patch) | |
tree | 365eada15165e37e153b6d304142db16f251438b /drivers/media/radio | |
parent | 2a383c63ff933a496f19d6559ab54ac14871b7f3 (diff) | |
parent | bbe2486fe3bd6c7cffaf4123b7e86a55c209ed44 (diff) |
Merge branch 'master' of ssh://master.kernel.org/pub/scm/linux/kernel/git/mchehab/v4l-dvb
* 'master' of ssh://master.kernel.org/pub/scm/linux/kernel/git/mchehab/v4l-dvb: (44 commits)
V4L/DVB (5571): V4l1-compat: Make VIDIOCSPICT return errors in a useful way
V4L/DVB (5624): Radio-maestro.c cleanup
V4L/DVB (5623): Dsbr100.c Replace usb_dsbr100_do_ioctl to use video_ioctl2
V4L/DVB (5622): Radio-zoltrix.c cleanup
V4L/DVB (5621): Radio-cadet.c Replace cadet_do_ioctl to use video_ioctl2
V4L/DVB (5619): Dvb-usb: fix typo
V4L/DVB (5618): Cx88: Drop the generic i2c client from cx88-vp3054-i2c
V4L/DVB (5617): V4L2: videodev, allow debugging
V4L/DVB (5614): M920x: Disable second adapter on LifeView TV Walker Twin
V4L/DVB (5613): M920x: loosen up 80-col limit
V4L/DVB (5612): M920x: rename function prefixes from m9206_foo to m920x_foo
V4L/DVB (5611): M920x: replace deb_rc with deb
V4L/DVB (5610): M920x: remove duplicated code
V4L/DVB (5609): M920x: group like functions together
V4L/DVB (5608): M920x: various whitespace cleanups
V4L/DVB (5607): M920x: Initial support for devices likely manufactured by Dposh
V4L/DVB (5606): M920x: add "c-basic-offset: 8" to help emacs to enforce tabbing
V4L/DVB (5605): M920x: Add support for LifeView TV Walker Twin
V4L/DVB (5603): V4L: Prevent queueing queued buffers.
V4L/DVB (5602): Enable DiSEqC in Starbox II (vp7021a)
...
Diffstat (limited to 'drivers/media/radio')
-rw-r--r-- | drivers/media/radio/Kconfig | 11 | ||||
-rw-r--r-- | drivers/media/radio/dsbr100.c | 345 | ||||
-rw-r--r-- | drivers/media/radio/radio-cadet.c | 297 | ||||
-rw-r--r-- | drivers/media/radio/radio-maestro.c | 3 | ||||
-rw-r--r-- | drivers/media/radio/radio-zoltrix.c | 1 |
5 files changed, 374 insertions, 283 deletions
diff --git a/drivers/media/radio/Kconfig b/drivers/media/radio/Kconfig index af66a5d5ecd8..a6ac82a609d4 100644 --- a/drivers/media/radio/Kconfig +++ b/drivers/media/radio/Kconfig | |||
@@ -2,8 +2,14 @@ | |||
2 | # Multimedia Video device configuration | 2 | # Multimedia Video device configuration |
3 | # | 3 | # |
4 | 4 | ||
5 | menu "Radio Adapters" | 5 | menuconfig RADIO_ADAPTERS |
6 | bool "Radio Adapters" | ||
6 | depends on VIDEO_DEV | 7 | depends on VIDEO_DEV |
8 | default y | ||
9 | ---help--- | ||
10 | Say Y here to enable selecting AM/FM radio adapters. | ||
11 | |||
12 | if RADIO_ADAPTERS | ||
7 | 13 | ||
8 | config RADIO_CADET | 14 | config RADIO_CADET |
9 | tristate "ADS Cadet AM/FM Tuner" | 15 | tristate "ADS Cadet AM/FM Tuner" |
@@ -328,4 +334,5 @@ config USB_DSBR | |||
328 | 334 | ||
329 | To compile this driver as a module, choose M here: the | 335 | To compile this driver as a module, choose M here: the |
330 | module will be called dsbr100. | 336 | module will be called dsbr100. |
331 | endmenu | 337 | |
338 | endif # RADIO_ADAPTERS | ||
diff --git a/drivers/media/radio/dsbr100.c b/drivers/media/radio/dsbr100.c index 449df1bb00d3..3bd07f7e3774 100644 --- a/drivers/media/radio/dsbr100.c +++ b/drivers/media/radio/dsbr100.c | |||
@@ -33,6 +33,10 @@ | |||
33 | 33 | ||
34 | History: | 34 | History: |
35 | 35 | ||
36 | Version 0.42: | ||
37 | Converted dsbr100 to use video_ioctl2 | ||
38 | by Douglas Landgraf <dougsland@gmail.com> | ||
39 | |||
36 | Version 0.41-ac1: | 40 | Version 0.41-ac1: |
37 | Alan Cox: Some cleanups and fixes | 41 | Alan Cox: Some cleanups and fixes |
38 | 42 | ||
@@ -121,8 +125,6 @@ devices, that would be 76 and 91. */ | |||
121 | static int usb_dsbr100_probe(struct usb_interface *intf, | 125 | static int usb_dsbr100_probe(struct usb_interface *intf, |
122 | const struct usb_device_id *id); | 126 | const struct usb_device_id *id); |
123 | static void usb_dsbr100_disconnect(struct usb_interface *intf); | 127 | static void usb_dsbr100_disconnect(struct usb_interface *intf); |
124 | static int usb_dsbr100_ioctl(struct inode *inode, struct file *file, | ||
125 | unsigned int cmd, unsigned long arg); | ||
126 | static int usb_dsbr100_open(struct inode *inode, struct file *file); | 128 | static int usb_dsbr100_open(struct inode *inode, struct file *file); |
127 | static int usb_dsbr100_close(struct inode *inode, struct file *file); | 129 | static int usb_dsbr100_close(struct inode *inode, struct file *file); |
128 | 130 | ||
@@ -142,26 +144,6 @@ struct dsbr100_device { | |||
142 | }; | 144 | }; |
143 | 145 | ||
144 | 146 | ||
145 | /* File system interface */ | ||
146 | static const struct file_operations usb_dsbr100_fops = { | ||
147 | .owner = THIS_MODULE, | ||
148 | .open = usb_dsbr100_open, | ||
149 | .release = usb_dsbr100_close, | ||
150 | .ioctl = usb_dsbr100_ioctl, | ||
151 | .compat_ioctl = v4l_compat_ioctl32, | ||
152 | .llseek = no_llseek, | ||
153 | }; | ||
154 | |||
155 | /* V4L interface */ | ||
156 | static struct video_device dsbr100_videodev_template= | ||
157 | { | ||
158 | .owner = THIS_MODULE, | ||
159 | .name = "D-Link DSB-R 100", | ||
160 | .type = VID_TYPE_TUNER, | ||
161 | .fops = &usb_dsbr100_fops, | ||
162 | .release = video_device_release, | ||
163 | }; | ||
164 | |||
165 | static struct usb_device_id usb_dsbr100_device_table [] = { | 147 | static struct usb_device_id usb_dsbr100_device_table [] = { |
166 | { USB_DEVICE(DSB100_VENDOR, DSB100_PRODUCT) }, | 148 | { USB_DEVICE(DSB100_VENDOR, DSB100_PRODUCT) }, |
167 | { } /* Terminating entry */ | 149 | { } /* Terminating entry */ |
@@ -252,37 +234,6 @@ static void dsbr100_getstat(struct dsbr100_device *radio) | |||
252 | 234 | ||
253 | /* USB subsystem interface begins here */ | 235 | /* USB subsystem interface begins here */ |
254 | 236 | ||
255 | /* check if the device is present and register with v4l and | ||
256 | usb if it is */ | ||
257 | static int usb_dsbr100_probe(struct usb_interface *intf, | ||
258 | const struct usb_device_id *id) | ||
259 | { | ||
260 | struct dsbr100_device *radio; | ||
261 | |||
262 | if (!(radio = kmalloc(sizeof(struct dsbr100_device), GFP_KERNEL))) | ||
263 | return -ENOMEM; | ||
264 | if (!(radio->videodev = video_device_alloc())) { | ||
265 | kfree(radio); | ||
266 | return -ENOMEM; | ||
267 | } | ||
268 | memcpy(radio->videodev, &dsbr100_videodev_template, | ||
269 | sizeof(dsbr100_videodev_template)); | ||
270 | radio->removed = 0; | ||
271 | radio->users = 0; | ||
272 | radio->usbdev = interface_to_usbdev(intf); | ||
273 | radio->curfreq = FREQ_MIN*FREQ_MUL; | ||
274 | video_set_drvdata(radio->videodev, radio); | ||
275 | if (video_register_device(radio->videodev, VFL_TYPE_RADIO, | ||
276 | radio_nr)) { | ||
277 | warn("Could not register video device"); | ||
278 | video_device_release(radio->videodev); | ||
279 | kfree(radio); | ||
280 | return -EIO; | ||
281 | } | ||
282 | usb_set_intfdata(intf, radio); | ||
283 | return 0; | ||
284 | } | ||
285 | |||
286 | /* handle unplugging of the device, release data structures | 237 | /* handle unplugging of the device, release data structures |
287 | if nothing keeps us from doing it. If something is still | 238 | if nothing keeps us from doing it. If something is still |
288 | keeping us busy, the release callback of v4l will take care | 239 | keeping us busy, the release callback of v4l will take care |
@@ -307,133 +258,147 @@ static void usb_dsbr100_disconnect(struct usb_interface *intf) | |||
307 | } | 258 | } |
308 | 259 | ||
309 | 260 | ||
310 | /* Video for Linux interface */ | 261 | static int vidioc_querycap(struct file *file, void *priv, |
262 | struct v4l2_capability *v) | ||
263 | { | ||
264 | strlcpy(v->driver, "dsbr100", sizeof(v->driver)); | ||
265 | strlcpy(v->card, "D-Link R-100 USB FM Radio", sizeof(v->card)); | ||
266 | sprintf(v->bus_info, "ISA"); | ||
267 | v->version = RADIO_VERSION; | ||
268 | v->capabilities = V4L2_CAP_TUNER; | ||
269 | return 0; | ||
270 | } | ||
311 | 271 | ||
312 | static int usb_dsbr100_do_ioctl(struct inode *inode, struct file *file, | 272 | static int vidioc_g_tuner(struct file *file, void *priv, |
313 | unsigned int cmd, void *arg) | 273 | struct v4l2_tuner *v) |
314 | { | 274 | { |
315 | struct dsbr100_device *radio=video_get_drvdata(video_devdata(file)); | 275 | struct dsbr100_device *radio = video_get_drvdata(video_devdata(file)); |
276 | |||
277 | if (v->index > 0) | ||
278 | return -EINVAL; | ||
279 | |||
280 | dsbr100_getstat(radio); | ||
281 | strcpy(v->name, "FM"); | ||
282 | v->type = V4L2_TUNER_RADIO; | ||
283 | v->rangelow = FREQ_MIN*FREQ_MUL; | ||
284 | v->rangehigh = FREQ_MAX*FREQ_MUL; | ||
285 | v->rxsubchans = V4L2_TUNER_SUB_MONO|V4L2_TUNER_SUB_STEREO; | ||
286 | v->capability = V4L2_TUNER_CAP_LOW; | ||
287 | if(radio->stereo) | ||
288 | v->audmode = V4L2_TUNER_MODE_STEREO; | ||
289 | else | ||
290 | v->audmode = V4L2_TUNER_MODE_MONO; | ||
291 | v->signal = 0xffff; /* We can't get the signal strength */ | ||
292 | return 0; | ||
293 | } | ||
316 | 294 | ||
317 | if (!radio) | 295 | static int vidioc_s_tuner(struct file *file, void *priv, |
318 | return -EIO; | 296 | struct v4l2_tuner *v) |
297 | { | ||
298 | if (v->index > 0) | ||
299 | return -EINVAL; | ||
319 | 300 | ||
320 | switch(cmd) { | 301 | return 0; |
321 | case VIDIOC_QUERYCAP: | 302 | } |
322 | { | ||
323 | struct v4l2_capability *v = arg; | ||
324 | memset(v,0,sizeof(*v)); | ||
325 | strlcpy(v->driver, "dsbr100", sizeof (v->driver)); | ||
326 | strlcpy(v->card, "D-Link R-100 USB FM Radio", sizeof (v->card)); | ||
327 | sprintf(v->bus_info,"ISA"); | ||
328 | v->version = RADIO_VERSION; | ||
329 | v->capabilities = V4L2_CAP_TUNER; | ||
330 | 303 | ||
331 | return 0; | 304 | static int vidioc_s_frequency(struct file *file, void *priv, |
332 | } | 305 | struct v4l2_frequency *f) |
333 | case VIDIOC_G_TUNER: | 306 | { |
334 | { | 307 | struct dsbr100_device *radio = video_get_drvdata(video_devdata(file)); |
335 | struct v4l2_tuner *v = arg; | ||
336 | 308 | ||
337 | if (v->index > 0) | 309 | radio->curfreq = f->frequency; |
338 | return -EINVAL; | 310 | if (dsbr100_setfreq(radio, radio->curfreq)==-1) |
311 | warn("Set frequency failed"); | ||
312 | return 0; | ||
313 | } | ||
339 | 314 | ||
340 | dsbr100_getstat(radio); | 315 | static int vidioc_g_frequency(struct file *file, void *priv, |
316 | struct v4l2_frequency *f) | ||
317 | { | ||
318 | struct dsbr100_device *radio = video_get_drvdata(video_devdata(file)); | ||
341 | 319 | ||
342 | memset(v,0,sizeof(*v)); | 320 | f->type = V4L2_TUNER_RADIO; |
343 | strcpy(v->name, "FM"); | 321 | f->frequency = radio->curfreq; |
344 | v->type = V4L2_TUNER_RADIO; | 322 | return 0; |
323 | } | ||
345 | 324 | ||
346 | v->rangelow = FREQ_MIN*FREQ_MUL; | 325 | static int vidioc_queryctrl(struct file *file, void *priv, |
347 | v->rangehigh = FREQ_MAX*FREQ_MUL; | 326 | struct v4l2_queryctrl *qc) |
348 | v->rxsubchans =V4L2_TUNER_SUB_MONO|V4L2_TUNER_SUB_STEREO; | 327 | { |
349 | v->capability=V4L2_TUNER_CAP_LOW; | 328 | int i; |
350 | if(radio->stereo) | ||
351 | v->audmode = V4L2_TUNER_MODE_STEREO; | ||
352 | else | ||
353 | v->audmode = V4L2_TUNER_MODE_MONO; | ||
354 | v->signal = 0xFFFF; /* We can't get the signal strength */ | ||
355 | 329 | ||
330 | for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) { | ||
331 | if (qc->id && qc->id == radio_qctrl[i].id) { | ||
332 | memcpy(qc, &(radio_qctrl[i]), | ||
333 | sizeof(*qc)); | ||
356 | return 0; | 334 | return 0; |
357 | } | 335 | } |
358 | case VIDIOC_S_TUNER: | 336 | } |
359 | { | 337 | return -EINVAL; |
360 | struct v4l2_tuner *v = arg; | 338 | } |
361 | |||
362 | if (v->index > 0) | ||
363 | return -EINVAL; | ||
364 | 339 | ||
365 | return 0; | 340 | static int vidioc_g_ctrl(struct file *file, void *priv, |
366 | } | 341 | struct v4l2_control *ctrl) |
367 | case VIDIOC_S_FREQUENCY: | 342 | { |
368 | { | 343 | struct dsbr100_device *radio = video_get_drvdata(video_devdata(file)); |
369 | struct v4l2_frequency *f = arg; | ||
370 | 344 | ||
371 | radio->curfreq = f->frequency; | 345 | switch (ctrl->id) { |
372 | if (dsbr100_setfreq(radio, radio->curfreq)==-1) | 346 | case V4L2_CID_AUDIO_MUTE: |
373 | warn("Set frequency failed"); | 347 | ctrl->value = radio->muted; |
374 | return 0; | 348 | return 0; |
375 | } | 349 | } |
376 | case VIDIOC_G_FREQUENCY: | 350 | return -EINVAL; |
377 | { | 351 | } |
378 | struct v4l2_frequency *f = arg; | ||
379 | 352 | ||
380 | f->type = V4L2_TUNER_RADIO; | 353 | static int vidioc_s_ctrl(struct file *file, void *priv, |
381 | f->frequency = radio->curfreq; | 354 | struct v4l2_control *ctrl) |
355 | { | ||
356 | struct dsbr100_device *radio = video_get_drvdata(video_devdata(file)); | ||
382 | 357 | ||
383 | return 0; | 358 | switch (ctrl->id) { |
384 | } | 359 | case V4L2_CID_AUDIO_MUTE: |
385 | case VIDIOC_QUERYCTRL: | 360 | if (ctrl->value) { |
386 | { | 361 | if (dsbr100_stop(radio)==-1) |
387 | struct v4l2_queryctrl *qc = arg; | 362 | warn("Radio did not respond properly"); |
388 | int i; | 363 | } else { |
389 | 364 | if (dsbr100_start(radio)==-1) | |
390 | for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) { | 365 | warn("Radio did not respond properly"); |
391 | if (qc->id && qc->id == radio_qctrl[i].id) { | ||
392 | memcpy(qc, &(radio_qctrl[i]), | ||
393 | sizeof(*qc)); | ||
394 | return 0; | ||
395 | } | ||
396 | } | ||
397 | return -EINVAL; | ||
398 | } | ||
399 | case VIDIOC_G_CTRL: | ||
400 | { | ||
401 | struct v4l2_control *ctrl= arg; | ||
402 | |||
403 | switch (ctrl->id) { | ||
404 | case V4L2_CID_AUDIO_MUTE: | ||
405 | ctrl->value=radio->muted; | ||
406 | return 0; | ||
407 | } | ||
408 | return -EINVAL; | ||
409 | } | ||
410 | case VIDIOC_S_CTRL: | ||
411 | { | ||
412 | struct v4l2_control *ctrl= arg; | ||
413 | |||
414 | switch (ctrl->id) { | ||
415 | case V4L2_CID_AUDIO_MUTE: | ||
416 | if (ctrl->value) { | ||
417 | if (dsbr100_stop(radio)==-1) | ||
418 | warn("Radio did not respond properly"); | ||
419 | } else { | ||
420 | if (dsbr100_start(radio)==-1) | ||
421 | warn("Radio did not respond properly"); | ||
422 | } | ||
423 | return 0; | ||
424 | } | ||
425 | return -EINVAL; | ||
426 | } | 366 | } |
427 | default: | 367 | return 0; |
428 | return v4l_compat_translate_ioctl(inode,file,cmd,arg, | ||
429 | usb_dsbr100_do_ioctl); | ||
430 | } | 368 | } |
369 | return -EINVAL; | ||
431 | } | 370 | } |
432 | 371 | ||
433 | static int usb_dsbr100_ioctl(struct inode *inode, struct file *file, | 372 | static int vidioc_g_audio(struct file *file, void *priv, |
434 | unsigned int cmd, unsigned long arg) | 373 | struct v4l2_audio *a) |
435 | { | 374 | { |
436 | return video_usercopy(inode, file, cmd, arg, usb_dsbr100_do_ioctl); | 375 | if (a->index > 1) |
376 | return -EINVAL; | ||
377 | |||
378 | strcpy(a->name, "Radio"); | ||
379 | a->capability = V4L2_AUDCAP_STEREO; | ||
380 | return 0; | ||
381 | } | ||
382 | |||
383 | static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i) | ||
384 | { | ||
385 | *i = 0; | ||
386 | return 0; | ||
387 | } | ||
388 | |||
389 | static int vidioc_s_input(struct file *filp, void *priv, unsigned int i) | ||
390 | { | ||
391 | if (i != 0) | ||
392 | return -EINVAL; | ||
393 | return 0; | ||
394 | } | ||
395 | |||
396 | static int vidioc_s_audio(struct file *file, void *priv, | ||
397 | struct v4l2_audio *a) | ||
398 | { | ||
399 | if (a->index != 0) | ||
400 | return -EINVAL; | ||
401 | return 0; | ||
437 | } | 402 | } |
438 | 403 | ||
439 | static int usb_dsbr100_open(struct inode *inode, struct file *file) | 404 | static int usb_dsbr100_open(struct inode *inode, struct file *file) |
@@ -465,6 +430,68 @@ static int usb_dsbr100_close(struct inode *inode, struct file *file) | |||
465 | return 0; | 430 | return 0; |
466 | } | 431 | } |
467 | 432 | ||
433 | /* File system interface */ | ||
434 | static const struct file_operations usb_dsbr100_fops = { | ||
435 | .owner = THIS_MODULE, | ||
436 | .open = usb_dsbr100_open, | ||
437 | .release = usb_dsbr100_close, | ||
438 | .ioctl = video_ioctl2, | ||
439 | .compat_ioctl = v4l_compat_ioctl32, | ||
440 | .llseek = no_llseek, | ||
441 | }; | ||
442 | |||
443 | /* V4L2 interface */ | ||
444 | static struct video_device dsbr100_videodev_template = | ||
445 | { | ||
446 | .owner = THIS_MODULE, | ||
447 | .name = "D-Link DSB-R 100", | ||
448 | .type = VID_TYPE_TUNER, | ||
449 | .fops = &usb_dsbr100_fops, | ||
450 | .release = video_device_release, | ||
451 | .vidioc_querycap = vidioc_querycap, | ||
452 | .vidioc_g_tuner = vidioc_g_tuner, | ||
453 | .vidioc_s_tuner = vidioc_s_tuner, | ||
454 | .vidioc_g_frequency = vidioc_g_frequency, | ||
455 | .vidioc_s_frequency = vidioc_s_frequency, | ||
456 | .vidioc_queryctrl = vidioc_queryctrl, | ||
457 | .vidioc_g_ctrl = vidioc_g_ctrl, | ||
458 | .vidioc_s_ctrl = vidioc_s_ctrl, | ||
459 | .vidioc_g_audio = vidioc_g_audio, | ||
460 | .vidioc_s_audio = vidioc_s_audio, | ||
461 | .vidioc_g_input = vidioc_g_input, | ||
462 | .vidioc_s_input = vidioc_s_input, | ||
463 | }; | ||
464 | |||
465 | /* check if the device is present and register with v4l and | ||
466 | usb if it is */ | ||
467 | static int usb_dsbr100_probe(struct usb_interface *intf, | ||
468 | const struct usb_device_id *id) | ||
469 | { | ||
470 | struct dsbr100_device *radio; | ||
471 | |||
472 | if (!(radio = kmalloc(sizeof(struct dsbr100_device), GFP_KERNEL))) | ||
473 | return -ENOMEM; | ||
474 | if (!(radio->videodev = video_device_alloc())) { | ||
475 | kfree(radio); | ||
476 | return -ENOMEM; | ||
477 | } | ||
478 | memcpy(radio->videodev, &dsbr100_videodev_template, | ||
479 | sizeof(dsbr100_videodev_template)); | ||
480 | radio->removed = 0; | ||
481 | radio->users = 0; | ||
482 | radio->usbdev = interface_to_usbdev(intf); | ||
483 | radio->curfreq = FREQ_MIN*FREQ_MUL; | ||
484 | video_set_drvdata(radio->videodev, radio); | ||
485 | if (video_register_device(radio->videodev, VFL_TYPE_RADIO,radio_nr)) { | ||
486 | warn("Could not register video device"); | ||
487 | video_device_release(radio->videodev); | ||
488 | kfree(radio); | ||
489 | return -EIO; | ||
490 | } | ||
491 | usb_set_intfdata(intf, radio); | ||
492 | return 0; | ||
493 | } | ||
494 | |||
468 | static int __init dsbr100_init(void) | 495 | static int __init dsbr100_init(void) |
469 | { | 496 | { |
470 | int retval = usb_register(&usb_dsbr100_driver); | 497 | int retval = usb_register(&usb_dsbr100_driver); |
diff --git a/drivers/media/radio/radio-cadet.c b/drivers/media/radio/radio-cadet.c index 8fbf0d8bd278..8cf2e9df5c8a 100644 --- a/drivers/media/radio/radio-cadet.c +++ b/drivers/media/radio/radio-cadet.c | |||
@@ -48,6 +48,25 @@ | |||
48 | 48 | ||
49 | #define CADET_VERSION KERNEL_VERSION(0,3,3) | 49 | #define CADET_VERSION KERNEL_VERSION(0,3,3) |
50 | 50 | ||
51 | static struct v4l2_queryctrl radio_qctrl[] = { | ||
52 | { | ||
53 | .id = V4L2_CID_AUDIO_MUTE, | ||
54 | .name = "Mute", | ||
55 | .minimum = 0, | ||
56 | .maximum = 1, | ||
57 | .default_value = 1, | ||
58 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
59 | },{ | ||
60 | .id = V4L2_CID_AUDIO_VOLUME, | ||
61 | .name = "Volume", | ||
62 | .minimum = 0, | ||
63 | .maximum = 0xff, | ||
64 | .step = 1, | ||
65 | .default_value = 0xff, | ||
66 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
67 | } | ||
68 | }; | ||
69 | |||
51 | static int io=-1; /* default to isapnp activation */ | 70 | static int io=-1; /* default to isapnp activation */ |
52 | static int radio_nr = -1; | 71 | static int radio_nr = -1; |
53 | static int users=0; | 72 | static int users=0; |
@@ -347,135 +366,165 @@ cadet_read(struct file *file, char __user *data, size_t count, loff_t *ppos) | |||
347 | } | 366 | } |
348 | 367 | ||
349 | 368 | ||
369 | static int vidioc_querycap(struct file *file, void *priv, | ||
370 | struct v4l2_capability *v) | ||
371 | { | ||
372 | v->capabilities = | ||
373 | V4L2_CAP_TUNER | | ||
374 | V4L2_CAP_READWRITE; | ||
375 | v->version = CADET_VERSION; | ||
376 | strcpy(v->driver, "ADS Cadet"); | ||
377 | strcpy(v->card, "ADS Cadet"); | ||
378 | return 0; | ||
379 | } | ||
350 | 380 | ||
351 | static int cadet_do_ioctl(struct inode *inode, struct file *file, | 381 | static int vidioc_g_tuner(struct file *file, void *priv, |
352 | unsigned int cmd, void *arg) | 382 | struct v4l2_tuner *v) |
353 | { | 383 | { |
354 | switch(cmd) | 384 | v->type = V4L2_TUNER_RADIO; |
355 | { | 385 | switch (v->index) { |
356 | case VIDIOC_QUERYCAP: | 386 | case 0: |
357 | { | 387 | strcpy(v->name, "FM"); |
358 | struct v4l2_capability *cap = arg; | 388 | v->capability = V4L2_TUNER_CAP_STEREO; |
359 | memset(cap,0,sizeof(*cap)); | 389 | v->rangelow = 1400; /* 87.5 MHz */ |
360 | cap->capabilities = | 390 | v->rangehigh = 1728; /* 108.0 MHz */ |
361 | V4L2_CAP_TUNER | | 391 | v->rxsubchans=cadet_getstereo(); |
362 | V4L2_CAP_READWRITE; | 392 | switch (v->rxsubchans){ |
363 | cap->version = CADET_VERSION; | 393 | case V4L2_TUNER_SUB_MONO: |
364 | strcpy(cap->driver, "ADS Cadet"); | 394 | v->audmode = V4L2_TUNER_MODE_MONO; |
365 | strcpy(cap->card, "ADS Cadet"); | 395 | break; |
366 | return 0; | 396 | case V4L2_TUNER_SUB_STEREO: |
397 | v->audmode = V4L2_TUNER_MODE_STEREO; | ||
398 | break; | ||
399 | default: ; | ||
367 | } | 400 | } |
368 | case VIDIOC_G_TUNER: | 401 | break; |
369 | { | 402 | case 1: |
370 | struct v4l2_tuner *t = arg; | 403 | strcpy(v->name, "AM"); |
371 | memset(t,0,sizeof(*t)); | 404 | v->capability = V4L2_TUNER_CAP_LOW; |
372 | t->type = V4L2_TUNER_RADIO; | 405 | v->rangelow = 8320; /* 520 kHz */ |
373 | switch (t->index) | 406 | v->rangehigh = 26400; /* 1650 kHz */ |
374 | { | 407 | v->rxsubchans = V4L2_TUNER_SUB_MONO; |
375 | case 0: strcpy(t->name, "FM"); | 408 | v->audmode = V4L2_TUNER_MODE_MONO; |
376 | t->capability = V4L2_TUNER_CAP_STEREO; | 409 | break; |
377 | t->rangelow = 1400; /* 87.5 MHz */ | 410 | default: |
378 | t->rangehigh = 1728; /* 108.0 MHz */ | 411 | return -EINVAL; |
379 | t->rxsubchans=cadet_getstereo(); | 412 | } |
380 | switch (t->rxsubchans){ | 413 | v->signal = sigstrength; /* We might need to modify scaling of this */ |
381 | case V4L2_TUNER_SUB_MONO: | 414 | return 0; |
382 | t->audmode = V4L2_TUNER_MODE_MONO; | 415 | } |
383 | break; | ||
384 | case V4L2_TUNER_SUB_STEREO: | ||
385 | t->audmode = V4L2_TUNER_MODE_STEREO; | ||
386 | break; | ||
387 | default: ; | ||
388 | } | ||
389 | break; | ||
390 | case 1: strcpy(t->name, "AM"); | ||
391 | t->capability = V4L2_TUNER_CAP_LOW; | ||
392 | t->rangelow = 8320; /* 520 kHz */ | ||
393 | t->rangehigh = 26400; /* 1650 kHz */ | ||
394 | t->rxsubchans = V4L2_TUNER_SUB_MONO; | ||
395 | t->audmode = V4L2_TUNER_MODE_MONO; | ||
396 | break; | ||
397 | default: | ||
398 | return -EINVAL; | ||
399 | } | ||
400 | 416 | ||
401 | t->signal = sigstrength; /* We might need to modify scaling of this */ | 417 | static int vidioc_s_tuner(struct file *file, void *priv, |
402 | return 0; | 418 | struct v4l2_tuner *v) |
403 | } | 419 | { |
404 | case VIDIOC_S_TUNER: | 420 | if((v->index != 0)&&(v->index != 1)) |
405 | { | 421 | return -EINVAL; |
406 | struct v4l2_tuner *t = arg; | 422 | curtuner = v->index; |
407 | if((t->index != 0)&&(t->index != 1)) | 423 | return 0; |
408 | return -EINVAL; | 424 | } |
409 | 425 | ||
410 | curtuner = t->index; | 426 | static int vidioc_g_frequency(struct file *file, void *priv, |
411 | return 0; | 427 | struct v4l2_frequency *f) |
412 | } | 428 | { |
413 | case VIDIOC_G_FREQUENCY: | 429 | f->tuner = curtuner; |
414 | { | 430 | f->type = V4L2_TUNER_RADIO; |
415 | struct v4l2_frequency *f = arg; | 431 | f->frequency = cadet_getfreq(); |
416 | memset(f,0,sizeof(*f)); | 432 | return 0; |
417 | f->tuner = curtuner; | 433 | } |
418 | f->type = V4L2_TUNER_RADIO; | 434 | |
419 | f->frequency = cadet_getfreq(); | 435 | |
420 | return 0; | 436 | static int vidioc_s_frequency(struct file *file, void *priv, |
421 | } | 437 | struct v4l2_frequency *f) |
422 | case VIDIOC_S_FREQUENCY: | 438 | { |
423 | { | 439 | if (f->type != V4L2_TUNER_RADIO) |
424 | struct v4l2_frequency *f = arg; | 440 | return -EINVAL; |
425 | if (f->type != V4L2_TUNER_RADIO){ | 441 | if((curtuner==0)&&((f->frequency<1400)||(f->frequency>1728))) |
426 | return -EINVAL; | 442 | return -EINVAL; |
427 | } | 443 | if((curtuner==1)&&((f->frequency<8320)||(f->frequency>26400))) |
428 | if((curtuner==0)&&((f->frequency<1400)||(f->frequency>1728))) { | 444 | return -EINVAL; |
429 | return -EINVAL; | 445 | cadet_setfreq(f->frequency); |
430 | } | 446 | return 0; |
431 | if((curtuner==1)&&((f->frequency<8320)||(f->frequency>26400))) { | 447 | } |
432 | return -EINVAL; | 448 | |
433 | } | 449 | static int vidioc_queryctrl(struct file *file, void *priv, |
434 | cadet_setfreq(f->frequency); | 450 | struct v4l2_queryctrl *qc) |
435 | return 0; | 451 | { |
436 | } | 452 | int i; |
437 | case VIDIOC_G_CTRL: | 453 | |
438 | { | 454 | for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) { |
439 | struct v4l2_control *c = arg; | 455 | if (qc->id && qc->id == radio_qctrl[i].id) { |
440 | switch (c->id){ | 456 | memcpy(qc, &(radio_qctrl[i]), |
441 | case V4L2_CID_AUDIO_MUTE: /* TODO: Handle this correctly */ | 457 | sizeof(*qc)); |
442 | c->value = (cadet_getvol() == 0); | ||
443 | break; | ||
444 | case V4L2_CID_AUDIO_VOLUME: | ||
445 | c->value = cadet_getvol(); | ||
446 | break; | ||
447 | default: | ||
448 | return -EINVAL; | ||
449 | } | ||
450 | return 0; | ||
451 | } | ||
452 | case VIDIOC_S_CTRL: | ||
453 | { | ||
454 | struct v4l2_control *c = arg; | ||
455 | switch (c->id){ | ||
456 | case V4L2_CID_AUDIO_MUTE: /* TODO: Handle this correctly */ | ||
457 | if (c->value) cadet_setvol(0); | ||
458 | else cadet_setvol(0xffff); | ||
459 | break; | ||
460 | case V4L2_CID_AUDIO_VOLUME: | ||
461 | cadet_setvol(c->value); | ||
462 | break; | ||
463 | default: | ||
464 | return -EINVAL; | ||
465 | } | ||
466 | return 0; | 458 | return 0; |
467 | } | 459 | } |
460 | } | ||
461 | return -EINVAL; | ||
462 | } | ||
468 | 463 | ||
469 | default: | 464 | static int vidioc_g_ctrl(struct file *file, void *priv, |
470 | return -ENOIOCTLCMD; | 465 | struct v4l2_control *ctrl) |
466 | { | ||
467 | switch (ctrl->id){ | ||
468 | case V4L2_CID_AUDIO_MUTE: /* TODO: Handle this correctly */ | ||
469 | ctrl->value = (cadet_getvol() == 0); | ||
470 | break; | ||
471 | case V4L2_CID_AUDIO_VOLUME: | ||
472 | ctrl->value = cadet_getvol(); | ||
473 | break; | ||
474 | default: | ||
475 | return -EINVAL; | ||
471 | } | 476 | } |
477 | return 0; | ||
472 | } | 478 | } |
473 | 479 | ||
474 | static int | 480 | static int vidioc_s_ctrl(struct file *file, void *priv, |
475 | cadet_ioctl(struct inode *inode, struct file *file, | 481 | struct v4l2_control *ctrl) |
476 | unsigned int cmd, unsigned long arg) | ||
477 | { | 482 | { |
478 | return video_usercopy(inode, file, cmd, arg, cadet_do_ioctl); | 483 | switch (ctrl->id){ |
484 | case V4L2_CID_AUDIO_MUTE: /* TODO: Handle this correctly */ | ||
485 | if (ctrl->value) | ||
486 | cadet_setvol(0); | ||
487 | else | ||
488 | cadet_setvol(0xffff); | ||
489 | break; | ||
490 | case V4L2_CID_AUDIO_VOLUME: | ||
491 | cadet_setvol(ctrl->value); | ||
492 | break; | ||
493 | default: | ||
494 | return -EINVAL; | ||
495 | } | ||
496 | return 0; | ||
497 | } | ||
498 | |||
499 | static int vidioc_g_audio(struct file *file, void *priv, | ||
500 | struct v4l2_audio *a) | ||
501 | { | ||
502 | if (a->index > 1) | ||
503 | return -EINVAL; | ||
504 | strcpy(a->name, "Radio"); | ||
505 | a->capability = V4L2_AUDCAP_STEREO; | ||
506 | return 0; | ||
507 | } | ||
508 | |||
509 | static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i) | ||
510 | { | ||
511 | *i = 0; | ||
512 | return 0; | ||
513 | } | ||
514 | |||
515 | static int vidioc_s_input(struct file *filp, void *priv, unsigned int i) | ||
516 | { | ||
517 | if (i != 0) | ||
518 | return -EINVAL; | ||
519 | return 0; | ||
520 | } | ||
521 | |||
522 | static int vidioc_s_audio(struct file *file, void *priv, | ||
523 | struct v4l2_audio *a) | ||
524 | { | ||
525 | if (a->index != 0) | ||
526 | return -EINVAL; | ||
527 | return 0; | ||
479 | } | 528 | } |
480 | 529 | ||
481 | static int | 530 | static int |
@@ -512,7 +561,7 @@ static const struct file_operations cadet_fops = { | |||
512 | .open = cadet_open, | 561 | .open = cadet_open, |
513 | .release = cadet_release, | 562 | .release = cadet_release, |
514 | .read = cadet_read, | 563 | .read = cadet_read, |
515 | .ioctl = cadet_ioctl, | 564 | .ioctl = video_ioctl2, |
516 | .poll = cadet_poll, | 565 | .poll = cadet_poll, |
517 | .compat_ioctl = v4l_compat_ioctl32, | 566 | .compat_ioctl = v4l_compat_ioctl32, |
518 | .llseek = no_llseek, | 567 | .llseek = no_llseek, |
@@ -524,6 +573,18 @@ static struct video_device cadet_radio= | |||
524 | .name = "Cadet radio", | 573 | .name = "Cadet radio", |
525 | .type = VID_TYPE_TUNER, | 574 | .type = VID_TYPE_TUNER, |
526 | .fops = &cadet_fops, | 575 | .fops = &cadet_fops, |
576 | .vidioc_querycap = vidioc_querycap, | ||
577 | .vidioc_g_tuner = vidioc_g_tuner, | ||
578 | .vidioc_s_tuner = vidioc_s_tuner, | ||
579 | .vidioc_g_frequency = vidioc_g_frequency, | ||
580 | .vidioc_s_frequency = vidioc_s_frequency, | ||
581 | .vidioc_queryctrl = vidioc_queryctrl, | ||
582 | .vidioc_g_ctrl = vidioc_g_ctrl, | ||
583 | .vidioc_s_ctrl = vidioc_s_ctrl, | ||
584 | .vidioc_g_audio = vidioc_g_audio, | ||
585 | .vidioc_s_audio = vidioc_s_audio, | ||
586 | .vidioc_g_input = vidioc_g_input, | ||
587 | .vidioc_s_input = vidioc_s_input, | ||
527 | }; | 588 | }; |
528 | 589 | ||
529 | static struct pnp_device_id cadet_pnp_devices[] = { | 590 | static struct pnp_device_id cadet_pnp_devices[] = { |
diff --git a/drivers/media/radio/radio-maestro.c b/drivers/media/radio/radio-maestro.c index 11f80cacd6ed..8e33a19a22a3 100644 --- a/drivers/media/radio/radio-maestro.c +++ b/drivers/media/radio/radio-maestro.c | |||
@@ -24,7 +24,6 @@ | |||
24 | #include <linux/delay.h> | 24 | #include <linux/delay.h> |
25 | #include <asm/io.h> | 25 | #include <asm/io.h> |
26 | #include <asm/uaccess.h> | 26 | #include <asm/uaccess.h> |
27 | #include <linux/mutex.h> | ||
28 | #include <linux/pci.h> | 27 | #include <linux/pci.h> |
29 | #include <linux/videodev2.h> | 28 | #include <linux/videodev2.h> |
30 | #include <media/v4l2-common.h> | 29 | #include <media/v4l2-common.h> |
@@ -110,7 +109,6 @@ struct radio_device { | |||
110 | muted, /* VIDEO_AUDIO_MUTE */ | 109 | muted, /* VIDEO_AUDIO_MUTE */ |
111 | stereo, /* VIDEO_TUNER_STEREO_ON */ | 110 | stereo, /* VIDEO_TUNER_STEREO_ON */ |
112 | tuned; /* signal strength (0 or 0xffff) */ | 111 | tuned; /* signal strength (0 or 0xffff) */ |
113 | struct mutex lock; | ||
114 | }; | 112 | }; |
115 | 113 | ||
116 | static u32 radio_bits_get(struct radio_device *dev) | 114 | static u32 radio_bits_get(struct radio_device *dev) |
@@ -394,7 +392,6 @@ static int __devinit maestro_probe(struct pci_dev *pdev, | |||
394 | } | 392 | } |
395 | 393 | ||
396 | radio_unit->io = pci_resource_start(pdev, 0) + GPIO_DATA; | 394 | radio_unit->io = pci_resource_start(pdev, 0) + GPIO_DATA; |
397 | mutex_init(&radio_unit->lock); | ||
398 | 395 | ||
399 | maestro_radio_inst = video_device_alloc(); | 396 | maestro_radio_inst = video_device_alloc(); |
400 | if (maestro_radio_inst == NULL) { | 397 | if (maestro_radio_inst == NULL) { |
diff --git a/drivers/media/radio/radio-zoltrix.c b/drivers/media/radio/radio-zoltrix.c index a4715901512d..203f4373eeb8 100644 --- a/drivers/media/radio/radio-zoltrix.c +++ b/drivers/media/radio/radio-zoltrix.c | |||
@@ -410,7 +410,6 @@ static struct video_device zoltrix_radio = | |||
410 | .owner = THIS_MODULE, | 410 | .owner = THIS_MODULE, |
411 | .name = "Zoltrix Radio Plus", | 411 | .name = "Zoltrix Radio Plus", |
412 | .type = VID_TYPE_TUNER, | 412 | .type = VID_TYPE_TUNER, |
413 | .hardware = 0, | ||
414 | .fops = &zoltrix_fops, | 413 | .fops = &zoltrix_fops, |
415 | .vidioc_querycap = vidioc_querycap, | 414 | .vidioc_querycap = vidioc_querycap, |
416 | .vidioc_g_tuner = vidioc_g_tuner, | 415 | .vidioc_g_tuner = vidioc_g_tuner, |