aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/radio/radio-cadet.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/radio/radio-cadet.c')
-rw-r--r--drivers/media/radio/radio-cadet.c297
1 files changed, 179 insertions, 118 deletions
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[] = {