diff options
Diffstat (limited to 'drivers/media/video/cx18/cx18-ioctl.c')
-rw-r--r-- | drivers/media/video/cx18/cx18-ioctl.c | 78 |
1 files changed, 59 insertions, 19 deletions
diff --git a/drivers/media/video/cx18/cx18-ioctl.c b/drivers/media/video/cx18/cx18-ioctl.c index 0ddf4dd55308..13ebd4a70f0d 100644 --- a/drivers/media/video/cx18/cx18-ioctl.c +++ b/drivers/media/video/cx18/cx18-ioctl.c | |||
@@ -372,15 +372,52 @@ static int cx18_g_chip_ident(struct file *file, void *fh, | |||
372 | struct v4l2_dbg_chip_ident *chip) | 372 | struct v4l2_dbg_chip_ident *chip) |
373 | { | 373 | { |
374 | struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; | 374 | struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; |
375 | int err = 0; | ||
375 | 376 | ||
376 | chip->ident = V4L2_IDENT_NONE; | 377 | chip->ident = V4L2_IDENT_NONE; |
377 | chip->revision = 0; | 378 | chip->revision = 0; |
378 | if (v4l2_chip_match_host(&chip->match)) { | 379 | switch (chip->match.type) { |
379 | chip->ident = V4L2_IDENT_CX23418; | 380 | case V4L2_CHIP_MATCH_HOST: |
380 | return 0; | 381 | switch (chip->match.addr) { |
382 | case 0: | ||
383 | chip->ident = V4L2_IDENT_CX23418; | ||
384 | chip->revision = cx18_read_reg(cx, 0xC72028); | ||
385 | break; | ||
386 | case 1: | ||
387 | /* | ||
388 | * The A/V decoder is always present, but in the rare | ||
389 | * case that the card doesn't have analog, we don't | ||
390 | * use it. We find it w/o using the cx->sd_av pointer | ||
391 | */ | ||
392 | cx18_call_hw(cx, CX18_HW_418_AV, | ||
393 | core, g_chip_ident, chip); | ||
394 | break; | ||
395 | default: | ||
396 | /* | ||
397 | * Could return ident = V4L2_IDENT_UNKNOWN if we had | ||
398 | * other host chips at higher addresses, but we don't | ||
399 | */ | ||
400 | err = -EINVAL; /* per V4L2 spec */ | ||
401 | break; | ||
402 | } | ||
403 | break; | ||
404 | case V4L2_CHIP_MATCH_I2C_DRIVER: | ||
405 | /* If needed, returns V4L2_IDENT_AMBIGUOUS without extra work */ | ||
406 | cx18_call_all(cx, core, g_chip_ident, chip); | ||
407 | break; | ||
408 | case V4L2_CHIP_MATCH_I2C_ADDR: | ||
409 | /* | ||
410 | * We could return V4L2_IDENT_UNKNOWN, but we don't do the work | ||
411 | * to look if a chip is at the address with no driver. That's a | ||
412 | * dangerous thing to do with EEPROMs anyway. | ||
413 | */ | ||
414 | cx18_call_all(cx, core, g_chip_ident, chip); | ||
415 | break; | ||
416 | default: | ||
417 | err = -EINVAL; | ||
418 | break; | ||
381 | } | 419 | } |
382 | cx18_call_i2c_clients(cx, VIDIOC_DBG_G_CHIP_IDENT, chip); | 420 | return err; |
383 | return 0; | ||
384 | } | 421 | } |
385 | 422 | ||
386 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 423 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
@@ -394,10 +431,10 @@ static int cx18_cxc(struct cx18 *cx, unsigned int cmd, void *arg) | |||
394 | return -EINVAL; | 431 | return -EINVAL; |
395 | 432 | ||
396 | regs->size = 4; | 433 | regs->size = 4; |
397 | if (cmd == VIDIOC_DBG_G_REGISTER) | 434 | if (cmd == VIDIOC_DBG_S_REGISTER) |
398 | regs->val = cx18_read_enc(cx, regs->reg); | ||
399 | else | ||
400 | cx18_write_enc(cx, regs->val, regs->reg); | 435 | cx18_write_enc(cx, regs->val, regs->reg); |
436 | else | ||
437 | regs->val = cx18_read_enc(cx, regs->reg); | ||
401 | return 0; | 438 | return 0; |
402 | } | 439 | } |
403 | 440 | ||
@@ -408,7 +445,8 @@ static int cx18_g_register(struct file *file, void *fh, | |||
408 | 445 | ||
409 | if (v4l2_chip_match_host(®->match)) | 446 | if (v4l2_chip_match_host(®->match)) |
410 | return cx18_cxc(cx, VIDIOC_DBG_G_REGISTER, reg); | 447 | return cx18_cxc(cx, VIDIOC_DBG_G_REGISTER, reg); |
411 | cx18_call_i2c_clients(cx, VIDIOC_DBG_G_REGISTER, reg); | 448 | /* FIXME - errors shouldn't be ignored */ |
449 | cx18_call_all(cx, core, g_register, reg); | ||
412 | return 0; | 450 | return 0; |
413 | } | 451 | } |
414 | 452 | ||
@@ -419,7 +457,8 @@ static int cx18_s_register(struct file *file, void *fh, | |||
419 | 457 | ||
420 | if (v4l2_chip_match_host(®->match)) | 458 | if (v4l2_chip_match_host(®->match)) |
421 | return cx18_cxc(cx, VIDIOC_DBG_S_REGISTER, reg); | 459 | return cx18_cxc(cx, VIDIOC_DBG_S_REGISTER, reg); |
422 | cx18_call_i2c_clients(cx, VIDIOC_DBG_S_REGISTER, reg); | 460 | /* FIXME - errors shouldn't be ignored */ |
461 | cx18_call_all(cx, core, s_register, reg); | ||
423 | return 0; | 462 | return 0; |
424 | } | 463 | } |
425 | #endif | 464 | #endif |
@@ -598,7 +637,7 @@ static int cx18_g_frequency(struct file *file, void *fh, | |||
598 | if (vf->tuner != 0) | 637 | if (vf->tuner != 0) |
599 | return -EINVAL; | 638 | return -EINVAL; |
600 | 639 | ||
601 | cx18_call_i2c_clients(cx, VIDIOC_G_FREQUENCY, vf); | 640 | cx18_call_all(cx, tuner, g_frequency, vf); |
602 | return 0; | 641 | return 0; |
603 | } | 642 | } |
604 | 643 | ||
@@ -617,7 +656,7 @@ int cx18_s_frequency(struct file *file, void *fh, struct v4l2_frequency *vf) | |||
617 | 656 | ||
618 | cx18_mute(cx); | 657 | cx18_mute(cx); |
619 | CX18_DEBUG_INFO("v4l2 ioctl: set frequency %d\n", vf->frequency); | 658 | CX18_DEBUG_INFO("v4l2 ioctl: set frequency %d\n", vf->frequency); |
620 | cx18_call_i2c_clients(cx, VIDIOC_S_FREQUENCY, vf); | 659 | cx18_call_all(cx, tuner, s_frequency, vf); |
621 | cx18_unmute(cx); | 660 | cx18_unmute(cx); |
622 | return 0; | 661 | return 0; |
623 | } | 662 | } |
@@ -666,7 +705,7 @@ int cx18_s_std(struct file *file, void *fh, v4l2_std_id *std) | |||
666 | (unsigned long long) cx->std); | 705 | (unsigned long long) cx->std); |
667 | 706 | ||
668 | /* Tuner */ | 707 | /* Tuner */ |
669 | cx18_call_i2c_clients(cx, VIDIOC_S_STD, &cx->std); | 708 | cx18_call_all(cx, tuner, s_std, cx->std); |
670 | return 0; | 709 | return 0; |
671 | } | 710 | } |
672 | 711 | ||
@@ -683,9 +722,7 @@ static int cx18_s_tuner(struct file *file, void *fh, struct v4l2_tuner *vt) | |||
683 | if (vt->index != 0) | 722 | if (vt->index != 0) |
684 | return -EINVAL; | 723 | return -EINVAL; |
685 | 724 | ||
686 | /* Setting tuner can only set audio mode */ | 725 | cx18_call_all(cx, tuner, s_tuner, vt); |
687 | cx18_call_i2c_clients(cx, VIDIOC_S_TUNER, vt); | ||
688 | |||
689 | return 0; | 726 | return 0; |
690 | } | 727 | } |
691 | 728 | ||
@@ -696,7 +733,7 @@ static int cx18_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt) | |||
696 | if (vt->index != 0) | 733 | if (vt->index != 0) |
697 | return -EINVAL; | 734 | return -EINVAL; |
698 | 735 | ||
699 | cx18_call_i2c_clients(cx, VIDIOC_G_TUNER, vt); | 736 | cx18_call_all(cx, tuner, g_tuner, vt); |
700 | 737 | ||
701 | if (test_bit(CX18_F_I_RADIO_USER, &cx->i_flags)) { | 738 | if (test_bit(CX18_F_I_RADIO_USER, &cx->i_flags)) { |
702 | strlcpy(vt->name, "cx18 Radio Tuner", sizeof(vt->name)); | 739 | strlcpy(vt->name, "cx18 Radio Tuner", sizeof(vt->name)); |
@@ -853,7 +890,7 @@ static int cx18_log_status(struct file *file, void *fh) | |||
853 | 890 | ||
854 | cx18_read_eeprom(cx, &tv); | 891 | cx18_read_eeprom(cx, &tv); |
855 | } | 892 | } |
856 | cx18_call_i2c_clients(cx, VIDIOC_LOG_STATUS, NULL); | 893 | cx18_call_all(cx, core, log_status); |
857 | cx18_get_input(cx, cx->active_input, &vidin); | 894 | cx18_get_input(cx, cx->active_input, &vidin); |
858 | cx18_get_audio_input(cx, cx->audio_input, &audin); | 895 | cx18_get_audio_input(cx, cx->audio_input, &audin); |
859 | CX18_INFO("Video Input: %s\n", vidin.name); | 896 | CX18_INFO("Video Input: %s\n", vidin.name); |
@@ -894,7 +931,8 @@ static long cx18_default(struct file *file, void *fh, int cmd, void *arg) | |||
894 | 931 | ||
895 | CX18_DEBUG_IOCTL("VIDIOC_INT_S_AUDIO_ROUTING(%d, %d)\n", | 932 | CX18_DEBUG_IOCTL("VIDIOC_INT_S_AUDIO_ROUTING(%d, %d)\n", |
896 | route->input, route->output); | 933 | route->input, route->output); |
897 | cx18_audio_set_route(cx, route); | 934 | cx18_call_hw(cx, cx->card->hw_audio_ctrl, audio, s_routing, |
935 | route); | ||
898 | break; | 936 | break; |
899 | } | 937 | } |
900 | 938 | ||
@@ -922,6 +960,8 @@ long cx18_v4l2_ioctl(struct file *filp, unsigned int cmd, | |||
922 | 960 | ||
923 | mutex_lock(&cx->serialize_lock); | 961 | mutex_lock(&cx->serialize_lock); |
924 | 962 | ||
963 | /* FIXME - consolidate v4l2_prio_check()'s here */ | ||
964 | |||
925 | if (cx18_debug & CX18_DBGFLG_IOCTL) | 965 | if (cx18_debug & CX18_DBGFLG_IOCTL) |
926 | vfd->debug = V4L2_DEBUG_IOCTL | V4L2_DEBUG_IOCTL_ARG; | 966 | vfd->debug = V4L2_DEBUG_IOCTL | V4L2_DEBUG_IOCTL_ARG; |
927 | res = video_ioctl2(filp, cmd, arg); | 967 | res = video_ioctl2(filp, cmd, arg); |