aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/cx18/cx18-ioctl.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/cx18/cx18-ioctl.c')
-rw-r--r--drivers/media/video/cx18/cx18-ioctl.c78
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(&reg->match)) 446 if (v4l2_chip_match_host(&reg->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(&reg->match)) 458 if (v4l2_chip_match_host(&reg->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);