From 03ba675c15fe86ace9d44dc86d769b6695621e69 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 7 Feb 2009 11:23:40 +0100 Subject: saa7146: implement v4l2_device support. From: Hans Verkuil Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/common/saa7146_core.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'linux/drivers/media/common') diff --git a/linux/drivers/media/common/saa7146_core.c b/linux/drivers/media/common/saa7146_core.c index 9bce837f3..ef11ab98c 100644 --- a/linux/drivers/media/common/saa7146_core.c +++ b/linux/drivers/media/common/saa7146_core.c @@ -367,13 +367,16 @@ static int saa7146_init_one(struct pci_dev *pci, const struct pci_device_id *ent ERR(("out of memory.\n")); goto out; } + err = v4l2_device_register(&pci->dev, &dev->v4l2_dev); + if (err) + goto err_free; DEB_EE(("pci:%p\n",pci)); err = pci_enable_device(pci); if (err < 0) { ERR(("pci_enable_device() failed.\n")); - goto err_free; + goto err_unreg; } /* enable bus-mastering */ @@ -456,8 +459,6 @@ static int saa7146_init_one(struct pci_dev *pci, const struct pci_device_id *ent INFO(("found saa7146 @ mem %p (revision %d, irq %d) (0x%04x,0x%04x).\n", dev->mem, dev->revision, pci->irq, pci->subsystem_vendor, pci->subsystem_device)); dev->ext = ext; - pci_set_drvdata(pci, dev); - mutex_init(&dev->lock); spin_lock_init(&dev->int_slock); spin_lock_init(&dev->slock); @@ -481,7 +482,7 @@ static int saa7146_init_one(struct pci_dev *pci, const struct pci_device_id *ent if (ext->attach(dev, pci_ext)) { DEB_D(("ext->attach() failed for %p. skipping device.\n",dev)); - goto err_unprobe; + goto err_free_i2c; } INIT_LIST_HEAD(&dev->item); @@ -492,8 +493,6 @@ static int saa7146_init_one(struct pci_dev *pci, const struct pci_device_id *ent out: return err; -err_unprobe: - pci_set_drvdata(pci, NULL); err_free_i2c: pci_free_consistent(pci, SAA7146_RPS_MEM, dev->d_i2c.cpu_addr, dev->d_i2c.dma_handle); @@ -511,6 +510,8 @@ err_release: pci_release_region(pci, 0); err_disable: pci_disable_device(pci); +err_unreg: + v4l2_device_unregister(&dev->v4l2_dev); err_free: kfree(dev); goto out; @@ -518,7 +519,8 @@ err_free: static void saa7146_remove_one(struct pci_dev *pdev) { - struct saa7146_dev* dev = pci_get_drvdata(pdev); + struct v4l2_device *v4l2_dev = pci_get_drvdata(pdev); + struct saa7146_dev *dev = container_of(v4l2_dev, struct saa7146_dev, v4l2_dev); struct { void *addr; dma_addr_t dma; @@ -532,6 +534,7 @@ static void saa7146_remove_one(struct pci_dev *pdev) DEB_EE(("dev:%p\n",dev)); dev->ext->detach(dev); + v4l2_device_unregister(&dev->v4l2_dev); /* shut down all video dma transfers */ saa7146_write(dev, MC1, 0x00ff0000); -- cgit v1.2.3 From 730fafde64c1efd147ec7f58edf1bc0cc24ef24b Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 7 Feb 2009 11:38:12 +0100 Subject: saa7146: i2c adapdata now points to v4l2_device. From: Hans Verkuil Prepare for converting to v4l2_subdev. Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/common/saa7146_core.c | 2 +- linux/drivers/media/common/saa7146_i2c.c | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) (limited to 'linux/drivers/media/common') diff --git a/linux/drivers/media/common/saa7146_core.c b/linux/drivers/media/common/saa7146_core.c index ef11ab98c..067a1f282 100644 --- a/linux/drivers/media/common/saa7146_core.c +++ b/linux/drivers/media/common/saa7146_core.c @@ -520,7 +520,7 @@ err_free: static void saa7146_remove_one(struct pci_dev *pdev) { struct v4l2_device *v4l2_dev = pci_get_drvdata(pdev); - struct saa7146_dev *dev = container_of(v4l2_dev, struct saa7146_dev, v4l2_dev); + struct saa7146_dev *dev = to_saa7146_dev(v4l2_dev); struct { void *addr; dma_addr_t dma; diff --git a/linux/drivers/media/common/saa7146_i2c.c b/linux/drivers/media/common/saa7146_i2c.c index 255b14551..f275846da 100644 --- a/linux/drivers/media/common/saa7146_i2c.c +++ b/linux/drivers/media/common/saa7146_i2c.c @@ -391,7 +391,8 @@ out: /* utility functions */ static int saa7146_i2c_xfer(struct i2c_adapter* adapter, struct i2c_msg *msg, int num) { - struct saa7146_dev* dev = i2c_get_adapdata(adapter); + struct v4l2_device *v4l2_dev = i2c_get_adapdata(adapter); + struct saa7146_dev *dev = to_saa7146_dev(v4l2_dev); /* use helper function to transfer data */ return saa7146_i2c_transfer(dev, msg, num, adapter->retries); @@ -423,7 +424,7 @@ int saa7146_i2c_adapter_prepare(struct saa7146_dev *dev, struct i2c_adapter *i2c if( NULL != i2c_adapter ) { BUG_ON(!i2c_adapter->class); - i2c_set_adapdata(i2c_adapter,dev); + i2c_set_adapdata(i2c_adapter, &dev->v4l2_dev); i2c_adapter->dev.parent = &dev->pci->dev; i2c_adapter->algo = &saa7146_algo; i2c_adapter->algo_data = NULL; -- cgit v1.2.3 From 735182acc722237aca3cd7c6e5fde27c965d8334 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 7 Feb 2009 11:45:08 +0100 Subject: saa7146: the adapter class will be NULL when v4l2_subdev is used. From: Hans Verkuil Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/common/saa7146_i2c.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'linux/drivers/media/common') diff --git a/linux/drivers/media/common/saa7146_i2c.c b/linux/drivers/media/common/saa7146_i2c.c index f275846da..68674799b 100644 --- a/linux/drivers/media/common/saa7146_i2c.c +++ b/linux/drivers/media/common/saa7146_i2c.c @@ -422,8 +422,12 @@ int saa7146_i2c_adapter_prepare(struct saa7146_dev *dev, struct i2c_adapter *i2c dev->i2c_bitrate = bitrate; saa7146_i2c_reset(dev); - if( NULL != i2c_adapter ) { + if (i2c_adapter) { +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22) + /* For kernels > 2.6.22 it can actually be NULL + when v4l2_subdev is used. */ BUG_ON(!i2c_adapter->class); +#endif i2c_set_adapdata(i2c_adapter, &dev->v4l2_dev); i2c_adapter->dev.parent = &dev->pci->dev; i2c_adapter->algo = &saa7146_algo; -- cgit v1.2.3 From 2f363ae420765f2ca6c9a3263649936f10f25138 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 7 Feb 2009 15:18:05 +0100 Subject: saa7146: convert saa7146 and mxb in particular to v4l2_subdev. From: Hans Verkuil Modified mxb to load the i2c modules through v4l2_subdev. So no more probing. Modified tea6415c and tea6420 to use the standard routing ops to do the routing, rather than using private commands. Dropped the private commands from tda9840 (they were never used except during initialization of the module). Added saa7146 support for VIDIOC_DBG_G_CHIP_IDENT. Converted saa5246a and saa5249 to v4l2_subdev. Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/common/saa7146_video.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) (limited to 'linux/drivers/media/common') diff --git a/linux/drivers/media/common/saa7146_video.c b/linux/drivers/media/common/saa7146_video.c index a0cf6dacf..6536853c1 100644 --- a/linux/drivers/media/common/saa7146_video.c +++ b/linux/drivers/media/common/saa7146_video.c @@ -1,4 +1,5 @@ #include +#include #include "compat.h" static int max_memory = 32; @@ -210,6 +211,7 @@ static struct v4l2_queryctrl controls[] = { .step = 1, .default_value = 128, .type = V4L2_CTRL_TYPE_INTEGER, + .flags = V4L2_CTRL_FLAG_SLIDER, },{ .id = V4L2_CID_CONTRAST, .name = "Contrast", @@ -218,6 +220,7 @@ static struct v4l2_queryctrl controls[] = { .step = 1, .default_value = 64, .type = V4L2_CTRL_TYPE_INTEGER, + .flags = V4L2_CTRL_FLAG_SLIDER, },{ .id = V4L2_CID_SATURATION, .name = "Saturation", @@ -226,15 +229,16 @@ static struct v4l2_queryctrl controls[] = { .step = 1, .default_value = 64, .type = V4L2_CTRL_TYPE_INTEGER, + .flags = V4L2_CTRL_FLAG_SLIDER, },{ .id = V4L2_CID_VFLIP, - .name = "Vertical flip", + .name = "Vertical Flip", .minimum = 0, .maximum = 1, .type = V4L2_CTRL_TYPE_BOOLEAN, },{ .id = V4L2_CID_HFLIP, - .name = "Horizontal flip", + .name = "Horizontal Flip", .minimum = 0, .maximum = 1, .type = V4L2_CTRL_TYPE_BOOLEAN, @@ -1113,6 +1117,22 @@ static int vidioc_streamoff(struct file *file, void *__fh, enum v4l2_buf_type ty return err; } +static int vidioc_g_chip_ident(struct file *file, void *__fh, + struct v4l2_dbg_chip_ident *chip) +{ + struct saa7146_fh *fh = __fh; + struct saa7146_dev *dev = fh->dev; + + chip->ident = V4L2_IDENT_NONE; + chip->revision = 0; + if (v4l2_chip_match_host(&chip->match)) { + chip->ident = V4L2_IDENT_SAA7146; + return 0; + } + return v4l2_device_call_until_err(&dev->v4l2_dev, 0, + core, g_chip_ident, chip); +} + #ifdef CONFIG_VIDEO_V4L1_COMPAT static int vidiocgmbuf(struct file *file, void *__fh, struct video_mbuf *mbuf) { @@ -1153,6 +1173,7 @@ const struct v4l2_ioctl_ops saa7146_video_ioctl_ops = { .vidioc_try_fmt_vid_overlay = vidioc_try_fmt_vid_overlay, .vidioc_s_fmt_vid_overlay = vidioc_s_fmt_vid_overlay, .vidioc_g_fmt_vbi_cap = vidioc_g_fmt_vbi_cap, + .vidioc_g_chip_ident = vidioc_g_chip_ident, .vidioc_overlay = vidioc_overlay, .vidioc_g_fbuf = vidioc_g_fbuf, -- cgit v1.2.3 From 7a1cf2bbfb14fef2c4debf9f474cd0ed65a7c65e Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 7 Feb 2009 15:25:05 +0100 Subject: saa7146: setting control while capturing should return EBUSY, not EINVAL. From: Hans Verkuil Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/common/saa7146_video.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'linux/drivers/media/common') diff --git a/linux/drivers/media/common/saa7146_video.c b/linux/drivers/media/common/saa7146_video.c index 6536853c1..240757afb 100644 --- a/linux/drivers/media/common/saa7146_video.c +++ b/linux/drivers/media/common/saa7146_video.c @@ -698,7 +698,7 @@ static int vidioc_s_ctrl(struct file *file, void *fh, struct v4l2_control *c) if (IS_CAPTURE_ACTIVE(fh) != 0) { DEB_D(("V4L2_CID_HFLIP while active capture.\n")); mutex_unlock(&dev->lock); - return -EINVAL; + return -EBUSY; } vv->hflip = c->value; break; @@ -706,7 +706,7 @@ static int vidioc_s_ctrl(struct file *file, void *fh, struct v4l2_control *c) if (IS_CAPTURE_ACTIVE(fh) != 0) { DEB_D(("V4L2_CID_VFLIP while active capture.\n")); mutex_unlock(&dev->lock); - return -EINVAL; + return -EBUSY; } vv->vflip = c->value; break; -- cgit v1.2.3 From 7c101a67fb72f74c1a2af5e2ab8e206a5fd9f5ff Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 8 Feb 2009 00:15:22 +0100 Subject: saa7146: prevent unnecessary loading of v4l2-common. From: Hans Verkuil Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/common/saa7146_video.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux/drivers/media/common') diff --git a/linux/drivers/media/common/saa7146_video.c b/linux/drivers/media/common/saa7146_video.c index 240757afb..b7d73b7fd 100644 --- a/linux/drivers/media/common/saa7146_video.c +++ b/linux/drivers/media/common/saa7146_video.c @@ -1125,7 +1125,7 @@ static int vidioc_g_chip_ident(struct file *file, void *__fh, chip->ident = V4L2_IDENT_NONE; chip->revision = 0; - if (v4l2_chip_match_host(&chip->match)) { + if (chip->match.type == V4L2_CHIP_MATCH_HOST && !chip->match.addr) { chip->ident = V4L2_IDENT_SAA7146; return 0; } -- cgit v1.2.3 From b857ad615158d8e49953055fb34cd55050d5ebf2 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 8 Feb 2009 00:42:33 +0100 Subject: saa7146: move v4l2 device registration to saa7146_vv. From: Hans Verkuil Doing the v4l2_device registration in the saa7146 core will make it dependent on v4l2, even for DVB-only boards. This registration and unregistration belongs in saa7146_vv instead. Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/common/saa7146_core.c | 14 +++++++------- linux/drivers/media/common/saa7146_fops.c | 11 +++++++++-- 2 files changed, 16 insertions(+), 9 deletions(-) (limited to 'linux/drivers/media/common') diff --git a/linux/drivers/media/common/saa7146_core.c b/linux/drivers/media/common/saa7146_core.c index 067a1f282..dfb4915a8 100644 --- a/linux/drivers/media/common/saa7146_core.c +++ b/linux/drivers/media/common/saa7146_core.c @@ -367,16 +367,13 @@ static int saa7146_init_one(struct pci_dev *pci, const struct pci_device_id *ent ERR(("out of memory.\n")); goto out; } - err = v4l2_device_register(&pci->dev, &dev->v4l2_dev); - if (err) - goto err_free; DEB_EE(("pci:%p\n",pci)); err = pci_enable_device(pci); if (err < 0) { ERR(("pci_enable_device() failed.\n")); - goto err_unreg; + goto err_free; } /* enable bus-mastering */ @@ -484,6 +481,10 @@ static int saa7146_init_one(struct pci_dev *pci, const struct pci_device_id *ent DEB_D(("ext->attach() failed for %p. skipping device.\n",dev)); goto err_free_i2c; } + /* V4L extensions will set the pci drvdata to the v4l2_device in the + attach() above. So for those cards that do not use V4L we have to + set it explicitly. */ + pci_set_drvdata(pci, &dev->v4l2_dev); INIT_LIST_HEAD(&dev->item); list_add_tail(&dev->item,&saa7146_devices); @@ -510,8 +511,6 @@ err_release: pci_release_region(pci, 0); err_disable: pci_disable_device(pci); -err_unreg: - v4l2_device_unregister(&dev->v4l2_dev); err_free: kfree(dev); goto out; @@ -534,7 +533,8 @@ static void saa7146_remove_one(struct pci_dev *pdev) DEB_EE(("dev:%p\n",dev)); dev->ext->detach(dev); - v4l2_device_unregister(&dev->v4l2_dev); + /* Zero the PCI drvdata after use. */ + pci_set_drvdata(pdev, NULL); /* shut down all video dma transfers */ saa7146_write(dev, MC1, 0x00ff0000); diff --git a/linux/drivers/media/common/saa7146_fops.c b/linux/drivers/media/common/saa7146_fops.c index c6cc8574a..90e1d1ebb 100644 --- a/linux/drivers/media/common/saa7146_fops.c +++ b/linux/drivers/media/common/saa7146_fops.c @@ -447,11 +447,17 @@ static void vv_callback(struct saa7146_dev *dev, unsigned long status) int saa7146_vv_init(struct saa7146_dev* dev, struct saa7146_ext_vv *ext_vv) { - struct saa7146_vv *vv = kzalloc(sizeof(struct saa7146_vv), GFP_KERNEL); + struct saa7146_vv *vv; + int err; + + err = v4l2_device_register(&dev->pci->dev, &dev->v4l2_dev); + if (err) + return err; + vv = kzalloc(sizeof(struct saa7146_vv), GFP_KERNEL); if (vv == NULL) { ERR(("out of memory. aborting.\n")); - return -1; + return -ENOMEM; } ext_vv->ops = saa7146_video_ioctl_ops; ext_vv->core_ops = &saa7146_video_ioctl_ops; @@ -497,6 +503,7 @@ int saa7146_vv_release(struct saa7146_dev* dev) DEB_EE(("dev:%p\n",dev)); + v4l2_device_unregister(&dev->v4l2_dev); pci_free_consistent(dev->pci, SAA7146_CLIPPING_MEM, vv->d_clipping.cpu_addr, vv->d_clipping.dma_handle); kfree(vv); dev->vv_data = NULL; -- cgit v1.2.3