aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/radio
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-05-11 15:57:16 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-05-11 15:57:16 -0400
commit57a44415beee38d1afcd8e1b5fad66f3414d2dac (patch)
tree365eada15165e37e153b6d304142db16f251438b /drivers/media/radio
parent2a383c63ff933a496f19d6559ab54ac14871b7f3 (diff)
parentbbe2486fe3bd6c7cffaf4123b7e86a55c209ed44 (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/Kconfig11
-rw-r--r--drivers/media/radio/dsbr100.c345
-rw-r--r--drivers/media/radio/radio-cadet.c297
-rw-r--r--drivers/media/radio/radio-maestro.c3
-rw-r--r--drivers/media/radio/radio-zoltrix.c1
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
5menu "Radio Adapters" 5menuconfig 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
12if RADIO_ADAPTERS
7 13
8config RADIO_CADET 14config 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.
331endmenu 337
338endif # 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. */
121static int usb_dsbr100_probe(struct usb_interface *intf, 125static int usb_dsbr100_probe(struct usb_interface *intf,
122 const struct usb_device_id *id); 126 const struct usb_device_id *id);
123static void usb_dsbr100_disconnect(struct usb_interface *intf); 127static void usb_dsbr100_disconnect(struct usb_interface *intf);
124static int usb_dsbr100_ioctl(struct inode *inode, struct file *file,
125 unsigned int cmd, unsigned long arg);
126static int usb_dsbr100_open(struct inode *inode, struct file *file); 128static int usb_dsbr100_open(struct inode *inode, struct file *file);
127static int usb_dsbr100_close(struct inode *inode, struct file *file); 129static 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 */
146static 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 */
156static 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
165static struct usb_device_id usb_dsbr100_device_table [] = { 147static 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
256usb if it is */
257static 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
287if nothing keeps us from doing it. If something is still 238if nothing keeps us from doing it. If something is still
288keeping us busy, the release callback of v4l will take care 239keeping 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 */ 261static 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
312static int usb_dsbr100_do_ioctl(struct inode *inode, struct file *file, 272static 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) 295static 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; 304static 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); 315static 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; 325static 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; 340static 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; 353static 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
433static int usb_dsbr100_ioctl(struct inode *inode, struct file *file, 372static 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
383static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
384{
385 *i = 0;
386 return 0;
387}
388
389static 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
396static 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
439static int usb_dsbr100_open(struct inode *inode, struct file *file) 404static 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 */
434static 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 */
444static 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
466usb if it is */
467static 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
468static int __init dsbr100_init(void) 495static 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
51static 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
51static int io=-1; /* default to isapnp activation */ 70static int io=-1; /* default to isapnp activation */
52static int radio_nr = -1; 71static int radio_nr = -1;
53static int users=0; 72static 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
369static 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
351static int cadet_do_ioctl(struct inode *inode, struct file *file, 381static 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 */ 417static 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; 426static 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; 436static 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 } 449static 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: 464static 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
474static int 480static int vidioc_s_ctrl(struct file *file, void *priv,
475cadet_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
499static 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
509static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
510{
511 *i = 0;
512 return 0;
513}
514
515static 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
522static 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
481static int 530static 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
529static struct pnp_device_id cadet_pnp_devices[] = { 590static 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
116static u32 radio_bits_get(struct radio_device *dev) 114static 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,