diff options
author | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
---|---|---|
committer | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
commit | ada47b5fe13d89735805b566185f4885f5a3f750 (patch) | |
tree | 644b88f8a71896307d71438e9b3af49126ffb22b /drivers/media/video/cx23885/cx23885-video.c | |
parent | 43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff) | |
parent | 3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff) |
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'drivers/media/video/cx23885/cx23885-video.c')
-rw-r--r-- | drivers/media/video/cx23885/cx23885-video.c | 114 |
1 files changed, 49 insertions, 65 deletions
diff --git a/drivers/media/video/cx23885/cx23885-video.c b/drivers/media/video/cx23885/cx23885-video.c index 654cc253cd50..2d3ac8b83dc3 100644 --- a/drivers/media/video/cx23885/cx23885-video.c +++ b/drivers/media/video/cx23885/cx23885-video.c | |||
@@ -35,6 +35,8 @@ | |||
35 | #include "cx23885.h" | 35 | #include "cx23885.h" |
36 | #include <media/v4l2-common.h> | 36 | #include <media/v4l2-common.h> |
37 | #include <media/v4l2-ioctl.h> | 37 | #include <media/v4l2-ioctl.h> |
38 | #include "cx23885-ioctl.h" | ||
39 | #include "tuner-xc2028.h" | ||
38 | 40 | ||
39 | MODULE_DESCRIPTION("v4l2 driver module for cx23885 based TV cards"); | 41 | MODULE_DESCRIPTION("v4l2 driver module for cx23885 based TV cards"); |
40 | MODULE_AUTHOR("Steven Toth <stoth@linuxtv.org>"); | 42 | MODULE_AUTHOR("Steven Toth <stoth@linuxtv.org>"); |
@@ -317,11 +319,11 @@ static struct video_device *cx23885_vdev_init(struct cx23885_dev *dev, | |||
317 | if (NULL == vfd) | 319 | if (NULL == vfd) |
318 | return NULL; | 320 | return NULL; |
319 | *vfd = *template; | 321 | *vfd = *template; |
320 | vfd->minor = -1; | ||
321 | vfd->v4l2_dev = &dev->v4l2_dev; | 322 | vfd->v4l2_dev = &dev->v4l2_dev; |
322 | vfd->release = video_device_release; | 323 | vfd->release = video_device_release; |
323 | snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)", | 324 | snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)", |
324 | dev->name, type, cx23885_boards[dev->board].name); | 325 | dev->name, type, cx23885_boards[dev->board].name); |
326 | video_set_drvdata(vfd, dev); | ||
325 | return vfd; | 327 | return vfd; |
326 | } | 328 | } |
327 | 329 | ||
@@ -401,6 +403,13 @@ static int cx23885_video_mux(struct cx23885_dev *dev, unsigned int input) | |||
401 | INPUT(input)->gpio2, INPUT(input)->gpio3); | 403 | INPUT(input)->gpio2, INPUT(input)->gpio3); |
402 | dev->input = input; | 404 | dev->input = input; |
403 | 405 | ||
406 | if (dev->board == CX23885_BOARD_MYGICA_X8506 || | ||
407 | dev->board == CX23885_BOARD_MAGICPRO_PROHDTVE2) { | ||
408 | /* Select Analog TV */ | ||
409 | if (INPUT(input)->type == CX23885_VMUX_TELEVISION) | ||
410 | cx23885_gpio_clear(dev, GPIO_0); | ||
411 | } | ||
412 | |||
404 | /* Tell the internal A/V decoder */ | 413 | /* Tell the internal A/V decoder */ |
405 | v4l2_subdev_call(dev->sd_cx25840, video, s_routing, | 414 | v4l2_subdev_call(dev->sd_cx25840, video, s_routing, |
406 | INPUT(input)->vmux, 0, 0); | 415 | INPUT(input)->vmux, 0, 0); |
@@ -708,46 +717,34 @@ static int get_resource(struct cx23885_fh *fh) | |||
708 | 717 | ||
709 | static int video_open(struct file *file) | 718 | static int video_open(struct file *file) |
710 | { | 719 | { |
711 | int minor = video_devdata(file)->minor; | 720 | struct video_device *vdev = video_devdata(file); |
712 | struct cx23885_dev *h, *dev = NULL; | 721 | struct cx23885_dev *dev = video_drvdata(file); |
713 | struct cx23885_fh *fh; | 722 | struct cx23885_fh *fh; |
714 | struct list_head *list; | ||
715 | enum v4l2_buf_type type = 0; | 723 | enum v4l2_buf_type type = 0; |
716 | int radio = 0; | 724 | int radio = 0; |
717 | 725 | ||
718 | lock_kernel(); | 726 | switch (vdev->vfl_type) { |
719 | list_for_each(list, &cx23885_devlist) { | 727 | case VFL_TYPE_GRABBER: |
720 | h = list_entry(list, struct cx23885_dev, devlist); | 728 | type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
721 | if (h->video_dev && | 729 | break; |
722 | h->video_dev->minor == minor) { | 730 | case VFL_TYPE_VBI: |
723 | dev = h; | 731 | type = V4L2_BUF_TYPE_VBI_CAPTURE; |
724 | type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | 732 | break; |
725 | } | 733 | case VFL_TYPE_RADIO: |
726 | if (h->vbi_dev && | 734 | radio = 1; |
727 | h->vbi_dev->minor == minor) { | 735 | break; |
728 | dev = h; | ||
729 | type = V4L2_BUF_TYPE_VBI_CAPTURE; | ||
730 | } | ||
731 | if (h->radio_dev && | ||
732 | h->radio_dev->minor == minor) { | ||
733 | radio = 1; | ||
734 | dev = h; | ||
735 | } | ||
736 | } | ||
737 | if (NULL == dev) { | ||
738 | unlock_kernel(); | ||
739 | return -ENODEV; | ||
740 | } | 736 | } |
741 | 737 | ||
742 | dprintk(1, "open minor=%d radio=%d type=%s\n", | 738 | dprintk(1, "open dev=%s radio=%d type=%s\n", |
743 | minor, radio, v4l2_type_names[type]); | 739 | video_device_node_name(vdev), radio, v4l2_type_names[type]); |
744 | 740 | ||
745 | /* allocate + initialize per filehandle data */ | 741 | /* allocate + initialize per filehandle data */ |
746 | fh = kzalloc(sizeof(*fh), GFP_KERNEL); | 742 | fh = kzalloc(sizeof(*fh), GFP_KERNEL); |
747 | if (NULL == fh) { | 743 | if (NULL == fh) |
748 | unlock_kernel(); | ||
749 | return -ENOMEM; | 744 | return -ENOMEM; |
750 | } | 745 | |
746 | lock_kernel(); | ||
747 | |||
751 | file->private_data = fh; | 748 | file->private_data = fh; |
752 | fh->dev = dev; | 749 | fh->dev = dev; |
753 | fh->radio = radio; | 750 | fh->radio = radio; |
@@ -1144,6 +1141,7 @@ static int cx23885_enum_input(struct cx23885_dev *dev, struct v4l2_input *i) | |||
1144 | [CX23885_VMUX_COMPOSITE3] = "Composite3", | 1141 | [CX23885_VMUX_COMPOSITE3] = "Composite3", |
1145 | [CX23885_VMUX_COMPOSITE4] = "Composite4", | 1142 | [CX23885_VMUX_COMPOSITE4] = "Composite4", |
1146 | [CX23885_VMUX_SVIDEO] = "S-Video", | 1143 | [CX23885_VMUX_SVIDEO] = "S-Video", |
1144 | [CX23885_VMUX_COMPONENT] = "Component", | ||
1147 | [CX23885_VMUX_TELEVISION] = "Television", | 1145 | [CX23885_VMUX_TELEVISION] = "Television", |
1148 | [CX23885_VMUX_CABLE] = "Cable TV", | 1146 | [CX23885_VMUX_CABLE] = "Cable TV", |
1149 | [CX23885_VMUX_DVB] = "DVB", | 1147 | [CX23885_VMUX_DVB] = "DVB", |
@@ -1312,34 +1310,6 @@ static int vidioc_s_frequency(struct file *file, void *priv, | |||
1312 | cx23885_set_freq(dev, f); | 1310 | cx23885_set_freq(dev, f); |
1313 | } | 1311 | } |
1314 | 1312 | ||
1315 | #ifdef CONFIG_VIDEO_ADV_DEBUG | ||
1316 | static int vidioc_g_register(struct file *file, void *fh, | ||
1317 | struct v4l2_dbg_register *reg) | ||
1318 | { | ||
1319 | struct cx23885_dev *dev = ((struct cx23885_fh *)fh)->dev; | ||
1320 | |||
1321 | if (!v4l2_chip_match_host(®->match)) | ||
1322 | return -EINVAL; | ||
1323 | |||
1324 | call_all(dev, core, g_register, reg); | ||
1325 | |||
1326 | return 0; | ||
1327 | } | ||
1328 | |||
1329 | static int vidioc_s_register(struct file *file, void *fh, | ||
1330 | struct v4l2_dbg_register *reg) | ||
1331 | { | ||
1332 | struct cx23885_dev *dev = ((struct cx23885_fh *)fh)->dev; | ||
1333 | |||
1334 | if (!v4l2_chip_match_host(®->match)) | ||
1335 | return -EINVAL; | ||
1336 | |||
1337 | call_all(dev, core, s_register, reg); | ||
1338 | |||
1339 | return 0; | ||
1340 | } | ||
1341 | #endif | ||
1342 | |||
1343 | /* ----------------------------------------------------------- */ | 1313 | /* ----------------------------------------------------------- */ |
1344 | 1314 | ||
1345 | static void cx23885_vid_timeout(unsigned long data) | 1315 | static void cx23885_vid_timeout(unsigned long data) |
@@ -1449,9 +1419,10 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { | |||
1449 | .vidioc_s_tuner = vidioc_s_tuner, | 1419 | .vidioc_s_tuner = vidioc_s_tuner, |
1450 | .vidioc_g_frequency = vidioc_g_frequency, | 1420 | .vidioc_g_frequency = vidioc_g_frequency, |
1451 | .vidioc_s_frequency = vidioc_s_frequency, | 1421 | .vidioc_s_frequency = vidioc_s_frequency, |
1422 | .vidioc_g_chip_ident = cx23885_g_chip_ident, | ||
1452 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 1423 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
1453 | .vidioc_g_register = vidioc_g_register, | 1424 | .vidioc_g_register = cx23885_g_register, |
1454 | .vidioc_s_register = vidioc_s_register, | 1425 | .vidioc_s_register = cx23885_s_register, |
1455 | #endif | 1426 | #endif |
1456 | }; | 1427 | }; |
1457 | 1428 | ||
@@ -1459,7 +1430,6 @@ static struct video_device cx23885_vbi_template; | |||
1459 | static struct video_device cx23885_video_template = { | 1430 | static struct video_device cx23885_video_template = { |
1460 | .name = "cx23885-video", | 1431 | .name = "cx23885-video", |
1461 | .fops = &video_fops, | 1432 | .fops = &video_fops, |
1462 | .minor = -1, | ||
1463 | .ioctl_ops = &video_ioctl_ops, | 1433 | .ioctl_ops = &video_ioctl_ops, |
1464 | .tvnorms = CX23885_NORMS, | 1434 | .tvnorms = CX23885_NORMS, |
1465 | .current_norm = V4L2_STD_NTSC_M, | 1435 | .current_norm = V4L2_STD_NTSC_M, |
@@ -1479,7 +1449,7 @@ void cx23885_video_unregister(struct cx23885_dev *dev) | |||
1479 | cx_clear(PCI_INT_MSK, 1); | 1449 | cx_clear(PCI_INT_MSK, 1); |
1480 | 1450 | ||
1481 | if (dev->video_dev) { | 1451 | if (dev->video_dev) { |
1482 | if (-1 != dev->video_dev->minor) | 1452 | if (video_is_registered(dev->video_dev)) |
1483 | video_unregister_device(dev->video_dev); | 1453 | video_unregister_device(dev->video_dev); |
1484 | else | 1454 | else |
1485 | video_device_release(dev->video_dev); | 1455 | video_device_release(dev->video_dev); |
@@ -1529,11 +1499,25 @@ int cx23885_video_register(struct cx23885_dev *dev) | |||
1529 | if (sd) { | 1499 | if (sd) { |
1530 | struct tuner_setup tun_setup; | 1500 | struct tuner_setup tun_setup; |
1531 | 1501 | ||
1502 | memset(&tun_setup, 0, sizeof(tun_setup)); | ||
1532 | tun_setup.mode_mask = T_ANALOG_TV; | 1503 | tun_setup.mode_mask = T_ANALOG_TV; |
1533 | tun_setup.type = dev->tuner_type; | 1504 | tun_setup.type = dev->tuner_type; |
1534 | tun_setup.addr = v4l2_i2c_subdev_addr(sd); | 1505 | tun_setup.addr = v4l2_i2c_subdev_addr(sd); |
1506 | tun_setup.tuner_callback = cx23885_tuner_callback; | ||
1535 | 1507 | ||
1536 | v4l2_subdev_call(sd, tuner, s_type_addr, &tun_setup); | 1508 | v4l2_subdev_call(sd, tuner, s_type_addr, &tun_setup); |
1509 | |||
1510 | if (dev->board == CX23885_BOARD_LEADTEK_WINFAST_PXTV1200) { | ||
1511 | struct xc2028_ctrl ctrl = { | ||
1512 | .fname = XC2028_DEFAULT_FIRMWARE, | ||
1513 | .max_len = 64 | ||
1514 | }; | ||
1515 | struct v4l2_priv_tun_config cfg = { | ||
1516 | .tuner = dev->tuner_type, | ||
1517 | .priv = &ctrl | ||
1518 | }; | ||
1519 | v4l2_subdev_call(sd, tuner, s_config, &cfg); | ||
1520 | } | ||
1537 | } | 1521 | } |
1538 | } | 1522 | } |
1539 | 1523 | ||
@@ -1548,8 +1532,8 @@ int cx23885_video_register(struct cx23885_dev *dev) | |||
1548 | dev->name); | 1532 | dev->name); |
1549 | goto fail_unreg; | 1533 | goto fail_unreg; |
1550 | } | 1534 | } |
1551 | printk(KERN_INFO "%s/0: registered device video%d [v4l2]\n", | 1535 | printk(KERN_INFO "%s/0: registered device %s [v4l2]\n", |
1552 | dev->name, dev->video_dev->num); | 1536 | dev->name, video_device_node_name(dev->video_dev)); |
1553 | /* initial device configuration */ | 1537 | /* initial device configuration */ |
1554 | mutex_lock(&dev->lock); | 1538 | mutex_lock(&dev->lock); |
1555 | cx23885_set_tvnorm(dev, dev->tvnorm); | 1539 | cx23885_set_tvnorm(dev, dev->tvnorm); |