summaryrefslogtreecommitdiff
path: root/linux/drivers/media/video/soc_camera.c
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@infradead.org>2008-04-15 12:12:36 -0300
committerMauro Carvalho Chehab <mchehab@infradead.org>2008-04-15 12:12:36 -0300
commitd8006eead13b16a2cd2fbaa0bcf07a6944798344 (patch)
tree63e2ee9c61fbba1f9e3c2fe3b20ee20c04a8b67a /linux/drivers/media/video/soc_camera.c
parent0b19553adedb9b1ee222def2c7d8e3e748038d31 (diff)
downloadmediapointer-dvb-s2-d8006eead13b16a2cd2fbaa0bcf07a6944798344.tar.gz
mediapointer-dvb-s2-d8006eead13b16a2cd2fbaa0bcf07a6944798344.tar.bz2
> Please, re-generate the affected V4L/DVB patches, without the PXA part. I'll
> keep those changes on hold, until I get a confirmation that the PXA side is > committed on mainstream. Reverted several changes on soc_camera From: Mauro Carvalho Chehab <mchehab@infradead.org> As asked by Guennadi: Mauro, please, drop commits 2f4a87873f13924871d7bb82e27d02d0e16fbe02 and 9b7d577c508e7765860e599c0e98d4ac3fbaa2aa from your tree and replace 5f1e5244ee6b9f139a262d5e7a930a41488afbbe with the version below. Due to that change, that happened on v4l-dvb -git tree, several patches broke. This patch reverts all broken stuff, keeping this tree in sync with v4l-dvb -git tree. I'm waiting for Guennadi to fix the broken patches and ask me to pull them again. Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'linux/drivers/media/video/soc_camera.c')
-rw-r--r--linux/drivers/media/video/soc_camera.c144
1 files changed, 56 insertions, 88 deletions
diff --git a/linux/drivers/media/video/soc_camera.c b/linux/drivers/media/video/soc_camera.c
index a1b92446c..124406683 100644
--- a/linux/drivers/media/video/soc_camera.c
+++ b/linux/drivers/media/video/soc_camera.c
@@ -38,9 +38,9 @@ format_by_fourcc(struct soc_camera_device *icd, unsigned int fourcc)
{
unsigned int i;
- for (i = 0; i < icd->num_formats; i++)
- if (icd->formats[i].fourcc == fourcc)
- return icd->formats + i;
+ for (i = 0; i < icd->ops->num_formats; i++)
+ if (icd->ops->formats[i].fourcc == fourcc)
+ return icd->ops->formats + i;
return NULL;
}
@@ -75,13 +75,12 @@ static int soc_camera_try_fmt_cap(struct file *file, void *priv,
return -EINVAL;
}
- /* test physical bus parameters */
- ret = ici->ops->try_bus_param(icd, f->fmt.pix.pixelformat);
- if (ret)
- return ret;
+ /* limit to host capabilities */
+ ret = ici->try_fmt_cap(ici, f);
- /* limit format to hardware capabilities */
- ret = ici->ops->try_fmt_cap(icd, f);
+ /* limit to sensor capabilities */
+ if (!ret)
+ ret = icd->ops->try_fmt_cap(icd, f);
/* calculate missing fields */
f->fmt.pix.field = field;
@@ -143,7 +142,9 @@ static int soc_camera_reqbufs(struct file *file, void *priv,
if (ret < 0)
return ret;
- return ici->ops->reqbufs(icf, p);
+ return ici->reqbufs(icf, p);
+
+ return ret;
}
static int soc_camera_querybuf(struct file *file, void *priv,
@@ -182,7 +183,6 @@ static int soc_camera_open(struct inode *inode, struct file *file)
struct soc_camera_device *icd;
struct soc_camera_host *ici;
struct soc_camera_file *icf;
- spinlock_t *lock;
int ret;
icf = vmalloc(sizeof(*icf));
@@ -202,25 +202,19 @@ static int soc_camera_open(struct inode *inode, struct file *file)
goto emgd;
}
- if (!try_module_get(ici->ops->owner)) {
+ if (!try_module_get(ici->owner)) {
dev_err(&icd->dev, "Couldn't lock capture bus driver.\n");
ret = -EINVAL;
goto emgi;
}
- icf->icd = icd;
-
- icf->lock = ici->ops->spinlock_alloc(icf);
- if (!icf->lock) {
- ret = -ENOMEM;
- goto esla;
- }
-
icd->use_count++;
+ icf->icd = icd;
+
/* Now we really have to activate the camera */
if (icd->use_count == 1) {
- ret = ici->ops->add(icd);
+ ret = ici->add(icd);
if (ret < 0) {
dev_err(&icd->dev, "Couldn't activate the camera: %d\n", ret);
icd->use_count--;
@@ -234,8 +228,8 @@ static int soc_camera_open(struct inode *inode, struct file *file)
dev_dbg(&icd->dev, "camera device open\n");
/* We must pass NULL as dev pointer, then all pci_* dma operations
- * transform to normal dma_* ones. */
- videobuf_queue_sg_init(&icf->vb_vidq, ici->vbq_ops, NULL, icf->lock,
+ * transform to normal dma_* ones. Do we need an irqlock? */
+ videobuf_queue_sg_init(&icf->vb_vidq, ici->vbq_ops, NULL, NULL,
V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_NONE,
ici->msize, icd);
@@ -243,12 +237,7 @@ static int soc_camera_open(struct inode *inode, struct file *file)
/* All errors are entered with the video_lock held */
eiciadd:
- lock = icf->lock;
- icf->lock = NULL;
- if (ici->ops->spinlock_free)
- ici->ops->spinlock_free(lock);
-esla:
- module_put(ici->ops->owner);
+ module_put(ici->owner);
emgi:
module_put(icd->ops->owner);
emgd:
@@ -263,20 +252,16 @@ static int soc_camera_close(struct inode *inode, struct file *file)
struct soc_camera_device *icd = icf->icd;
struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
struct video_device *vdev = icd->vdev;
- spinlock_t *lock = icf->lock;
mutex_lock(&video_lock);
icd->use_count--;
if (!icd->use_count)
- ici->ops->remove(icd);
- icf->lock = NULL;
- if (ici->ops->spinlock_free)
- ici->ops->spinlock_free(lock);
+ ici->remove(icd);
module_put(icd->ops->owner);
- module_put(ici->ops->owner);
+ module_put(ici->owner);
mutex_unlock(&video_lock);
- vfree(icf);
+ vfree(file->private_data);
dev_dbg(vdev->dev, "camera device close\n");
@@ -326,7 +311,7 @@ static unsigned int soc_camera_poll(struct file *file, poll_table *pt)
return POLLERR;
}
- return ici->ops->poll(file, pt);
+ return ici->poll(file, pt);
}
@@ -359,8 +344,8 @@ static int soc_camera_s_fmt_cap(struct file *file, void *priv,
if (!data_fmt)
return -EINVAL;
- /* buswidth may be further adjusted by the ici */
- icd->buswidth = data_fmt->depth;
+ /* cached_datawidth may be further adjusted by the ici */
+ icd->cached_datawidth = data_fmt->depth;
ret = soc_camera_try_fmt_cap(file, icf, f);
if (ret < 0)
@@ -370,23 +355,22 @@ static int soc_camera_s_fmt_cap(struct file *file, void *priv,
rect.top = icd->y_current;
rect.width = f->fmt.pix.width;
rect.height = f->fmt.pix.height;
- ret = ici->ops->set_fmt_cap(icd, f->fmt.pix.pixelformat, &rect);
- if (ret < 0)
- return ret;
-
- icd->current_fmt = data_fmt;
- icd->width = rect.width;
- icd->height = rect.height;
- icf->vb_vidq.field = f->fmt.pix.field;
- if (V4L2_BUF_TYPE_VIDEO_CAPTURE != f->type)
- dev_warn(&icd->dev, "Attention! Wrong buf-type %d\n",
- f->type);
+ ret = ici->set_capture_format(icd, f->fmt.pix.pixelformat, &rect);
- dev_dbg(&icd->dev, "set width: %d height: %d\n",
- icd->width, icd->height);
+ if (!ret) {
+ icd->current_fmt = data_fmt;
+ icd->width = rect.width;
+ icd->height = rect.height;
+ icf->vb_vidq.field = f->fmt.pix.field;
+ if (V4L2_BUF_TYPE_VIDEO_CAPTURE != f->type)
+ dev_warn(&icd->dev, "Attention! Wrong buf-type %d\n",
+ f->type);
+
+ dev_dbg(&icd->dev, "set width: %d height: %d\n",
+ icd->width, icd->height);
+ }
- /* set physical bus parameters */
- return ici->ops->set_bus_param(icd, f->fmt.pix.pixelformat);
+ return ret;
}
static int soc_camera_enum_fmt_cap(struct file *file, void *priv,
@@ -398,10 +382,10 @@ static int soc_camera_enum_fmt_cap(struct file *file, void *priv,
WARN_ON(priv != file->private_data);
- if (f->index >= icd->num_formats)
+ if (f->index >= icd->ops->num_formats)
return -EINVAL;
- format = &icd->formats[f->index];
+ format = &icd->ops->formats[f->index];
strlcpy(f->description, format->name, sizeof(f->description));
f->pixelformat = format->fourcc;
@@ -440,7 +424,7 @@ static int soc_camera_querycap(struct file *file, void *priv,
WARN_ON(priv != file->private_data);
strlcpy(cap->driver, ici->drv_name, sizeof(cap->driver));
- return ici->ops->querycap(ici, cap);
+ return ici->querycap(ici, cap);
}
static int soc_camera_streamon(struct file *file, void *priv,
@@ -593,7 +577,7 @@ static int soc_camera_s_crop(struct file *file, void *fh,
if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
return -EINVAL;
- ret = ici->ops->set_fmt_cap(icd, 0, &a->c);
+ ret = ici->set_capture_format(icd, 0, &a->c);
if (!ret) {
icd->width = a->c.width;
icd->height = a->c.height;
@@ -715,16 +699,16 @@ static int soc_camera_probe(struct device *dev)
to_soc_camera_host(icd->dev.parent);
int ret;
- if (!icd->ops->probe)
+ if (!icd->probe)
return -ENODEV;
/* We only call ->add() here to activate and probe the camera.
* We shall ->remove() and deactivate it immediately afterwards. */
- ret = ici->ops->add(icd);
+ ret = ici->add(icd);
if (ret < 0)
return ret;
- ret = icd->ops->probe(icd);
+ ret = icd->probe(icd);
if (ret >= 0) {
const struct v4l2_queryctrl *qctrl;
@@ -734,7 +718,7 @@ static int soc_camera_probe(struct device *dev)
icd->exposure = qctrl ? qctrl->default_value :
(unsigned short)~0;
}
- ici->ops->remove(icd);
+ ici->remove(icd);
return ret;
}
@@ -745,8 +729,8 @@ static int soc_camera_remove(struct device *dev)
{
struct soc_camera_device *icd = to_soc_camera_dev(dev);
- if (icd->ops->remove)
- icd->ops->remove(icd);
+ if (icd->remove)
+ icd->remove(icd);
return 0;
}
@@ -776,27 +760,12 @@ static void dummy_release(struct device *dev)
{
}
-static spinlock_t *spinlock_alloc(struct soc_camera_file *icf)
-{
- spinlock_t *lock = kmalloc(sizeof(spinlock_t), GFP_KERNEL);
-
- if (lock)
- spin_lock_init(lock);
-
- return lock;
-}
-
-static void spinlock_free(spinlock_t *lock)
-{
- kfree(lock);
-}
-
-int soc_camera_host_register(struct soc_camera_host *ici)
+int soc_camera_host_register(struct soc_camera_host *ici, struct module *owner)
{
int ret;
struct soc_camera_host *ix;
- if (!ici->vbq_ops || !ici->ops->add || !ici->ops->remove)
+ if (!ici->vbq_ops || !ici->add || !ici->remove || !owner)
return -EINVAL;
/* Number might be equal to the platform device ID */
@@ -814,6 +783,7 @@ int soc_camera_host_register(struct soc_camera_host *ici)
list_add_tail(&ici->list, &hosts);
mutex_unlock(&list_lock);
+ ici->owner = owner;
ici->dev.release = dummy_release;
ret = device_register(&ici->dev);
@@ -821,11 +791,6 @@ int soc_camera_host_register(struct soc_camera_host *ici)
if (ret)
goto edevr;
- if (!ici->ops->spinlock_alloc) {
- ici->ops->spinlock_alloc = spinlock_alloc;
- ici->ops->spinlock_free = spinlock_free;
- }
-
scan_add_host(ici);
return 0;
@@ -852,7 +817,7 @@ void soc_camera_host_unregister(struct soc_camera_host *ici)
if (icd->dev.parent == &ici->dev) {
device_unregister(&icd->dev);
/* Not before device_unregister(), .remove
- * needs parent to call ici->ops->remove() */
+ * needs parent to call ici->remove() */
icd->dev.parent = NULL;
memset(&icd->dev.kobj, 0, sizeof(icd->dev.kobj));
}
@@ -895,6 +860,9 @@ int soc_camera_device_register(struct soc_camera_device *icd)
icd->dev.release = dummy_release;
+ if (icd->ops->get_datawidth)
+ icd->cached_datawidth = icd->ops->get_datawidth(icd);
+
return scan_add_device(icd);
}
EXPORT_SYMBOL(soc_camera_device_register);
@@ -961,7 +929,7 @@ int soc_camera_video_start(struct soc_camera_device *icd)
vdev->vidioc_s_register = soc_camera_s_register;
#endif
- icd->current_fmt = &icd->formats[0];
+ icd->current_fmt = &icd->ops->formats[0];
err = video_register_device(vdev, VFL_TYPE_GRABBER, vdev->minor);
if (err < 0) {