aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/cx23885/cx23885-video.c
diff options
context:
space:
mode:
authorAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
committerAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
commitada47b5fe13d89735805b566185f4885f5a3f750 (patch)
tree644b88f8a71896307d71438e9b3af49126ffb22b /drivers/media/video/cx23885/cx23885-video.c
parent43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff)
parent3280f21d43ee541f97f8cda5792150d2dbec20d5 (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.c114
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
39MODULE_DESCRIPTION("v4l2 driver module for cx23885 based TV cards"); 41MODULE_DESCRIPTION("v4l2 driver module for cx23885 based TV cards");
40MODULE_AUTHOR("Steven Toth <stoth@linuxtv.org>"); 42MODULE_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
709static int video_open(struct file *file) 718static 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
1316static 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(&reg->match))
1322 return -EINVAL;
1323
1324 call_all(dev, core, g_register, reg);
1325
1326 return 0;
1327}
1328
1329static 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(&reg->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
1345static void cx23885_vid_timeout(unsigned long data) 1315static 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;
1459static struct video_device cx23885_video_template = { 1430static 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);