summaryrefslogtreecommitdiffstats
path: root/drivers/media/video/soc_camera.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/soc_camera.c')
-rw-r--r--drivers/media/video/soc_camera.c124
1 files changed, 44 insertions, 80 deletions
diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c
index d015bfe00950..b6be5ee678b6 100644
--- a/drivers/media/video/soc_camera.c
+++ b/drivers/media/video/soc_camera.c
@@ -25,7 +25,9 @@
#include <linux/vmalloc.h>
#include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
#include <media/v4l2-dev.h>
+#include <media/videobuf-core.h>
#include <media/soc_camera.h>
static LIST_HEAD(hosts);
@@ -44,7 +46,7 @@ format_by_fourcc(struct soc_camera_device *icd, unsigned int fourcc)
return NULL;
}
-static int soc_camera_try_fmt_cap(struct file *file, void *priv,
+static int soc_camera_try_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
struct soc_camera_file *icf = file->private_data;
@@ -182,7 +184,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));
@@ -193,7 +194,7 @@ static int soc_camera_open(struct inode *inode, struct file *file)
mutex_lock(&video_lock);
vdev = video_devdata(file);
- icd = container_of(vdev->dev, struct soc_camera_device, dev);
+ icd = container_of(vdev->parent, struct soc_camera_device, dev);
ici = to_soc_camera_host(icd->dev.parent);
if (!try_module_get(icd->ops->owner)) {
@@ -209,13 +210,6 @@ static int soc_camera_open(struct inode *inode, struct file *file)
}
icf->icd = icd;
-
- icf->lock = ici->ops->spinlock_alloc(icf);
- if (!icf->lock) {
- ret = -ENOMEM;
- goto esla;
- }
-
icd->use_count++;
/* Now we really have to activate the camera */
@@ -233,21 +227,12 @@ static int soc_camera_open(struct inode *inode, struct file *file)
file->private_data = icf;
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,
- V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_NONE,
- ici->msize, icd);
+ ici->ops->init_videobuf(&icf->vb_vidq, icd);
return 0;
/* 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);
emgi:
module_put(icd->ops->owner);
@@ -263,22 +248,18 @@ 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);
module_put(icd->ops->owner);
module_put(ici->ops->owner);
mutex_unlock(&video_lock);
vfree(icf);
- dev_dbg(vdev->dev, "camera device close\n");
+ dev_dbg(vdev->parent, "camera device close\n");
return 0;
}
@@ -291,7 +272,7 @@ static ssize_t soc_camera_read(struct file *file, char __user *buf,
struct video_device *vdev = icd->vdev;
int err = -EINVAL;
- dev_err(vdev->dev, "camera device read not implemented\n");
+ dev_err(vdev->parent, "camera device read not implemented\n");
return err;
}
@@ -342,7 +323,7 @@ static struct file_operations soc_camera_fops = {
};
-static int soc_camera_s_fmt_cap(struct file *file, void *priv,
+static int soc_camera_s_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
struct soc_camera_file *icf = file->private_data;
@@ -362,7 +343,7 @@ static int soc_camera_s_fmt_cap(struct file *file, void *priv,
/* buswidth may be further adjusted by the ici */
icd->buswidth = data_fmt->depth;
- ret = soc_camera_try_fmt_cap(file, icf, f);
+ ret = soc_camera_try_fmt_vid_cap(file, icf, f);
if (ret < 0)
return ret;
@@ -389,7 +370,7 @@ static int soc_camera_s_fmt_cap(struct file *file, void *priv,
return ici->ops->set_bus_param(icd, f->fmt.pix.pixelformat);
}
-static int soc_camera_enum_fmt_cap(struct file *file, void *priv,
+static int soc_camera_enum_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_fmtdesc *f)
{
struct soc_camera_file *icf = file->private_data;
@@ -408,7 +389,7 @@ static int soc_camera_enum_fmt_cap(struct file *file, void *priv,
return 0;
}
-static int soc_camera_g_fmt_cap(struct file *file, void *priv,
+static int soc_camera_g_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
struct soc_camera_file *icf = file->private_data;
@@ -767,27 +748,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 ret;
struct soc_camera_host *ix;
- if (!ici->vbq_ops || !ici->ops->add || !ici->ops->remove)
+ if (!ici->ops->init_videobuf || !ici->ops->add || !ici->ops->remove)
return -EINVAL;
/* Number might be equal to the platform device ID */
@@ -811,11 +777,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;
@@ -901,6 +862,35 @@ void soc_camera_device_unregister(struct soc_camera_device *icd)
}
EXPORT_SYMBOL(soc_camera_device_unregister);
+static const struct v4l2_ioctl_ops soc_camera_ioctl_ops = {
+ .vidioc_querycap = soc_camera_querycap,
+ .vidioc_g_fmt_vid_cap = soc_camera_g_fmt_vid_cap,
+ .vidioc_enum_fmt_vid_cap = soc_camera_enum_fmt_vid_cap,
+ .vidioc_s_fmt_vid_cap = soc_camera_s_fmt_vid_cap,
+ .vidioc_enum_input = soc_camera_enum_input,
+ .vidioc_g_input = soc_camera_g_input,
+ .vidioc_s_input = soc_camera_s_input,
+ .vidioc_s_std = soc_camera_s_std,
+ .vidioc_reqbufs = soc_camera_reqbufs,
+ .vidioc_try_fmt_vid_cap = soc_camera_try_fmt_vid_cap,
+ .vidioc_querybuf = soc_camera_querybuf,
+ .vidioc_qbuf = soc_camera_qbuf,
+ .vidioc_dqbuf = soc_camera_dqbuf,
+ .vidioc_streamon = soc_camera_streamon,
+ .vidioc_streamoff = soc_camera_streamoff,
+ .vidioc_queryctrl = soc_camera_queryctrl,
+ .vidioc_g_ctrl = soc_camera_g_ctrl,
+ .vidioc_s_ctrl = soc_camera_s_ctrl,
+ .vidioc_cropcap = soc_camera_cropcap,
+ .vidioc_g_crop = soc_camera_g_crop,
+ .vidioc_s_crop = soc_camera_s_crop,
+ .vidioc_g_chip_ident = soc_camera_g_chip_ident,
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+ .vidioc_g_register = soc_camera_g_register,
+ .vidioc_s_register = soc_camera_s_register,
+#endif
+};
+
int soc_camera_video_start(struct soc_camera_device *icd)
{
struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
@@ -917,45 +907,19 @@ int soc_camera_video_start(struct soc_camera_device *icd)
strlcpy(vdev->name, ici->drv_name, sizeof(vdev->name));
/* Maybe better &ici->dev */
- vdev->dev = &icd->dev;
- vdev->type = VID_TYPE_CAPTURE;
+ vdev->parent = &icd->dev;
vdev->current_norm = V4L2_STD_UNKNOWN;
vdev->fops = &soc_camera_fops;
+ vdev->ioctl_ops = &soc_camera_ioctl_ops;
vdev->release = video_device_release;
vdev->minor = -1;
vdev->tvnorms = V4L2_STD_UNKNOWN,
- vdev->vidioc_querycap = soc_camera_querycap;
- vdev->vidioc_g_fmt_cap = soc_camera_g_fmt_cap;
- vdev->vidioc_enum_fmt_cap = soc_camera_enum_fmt_cap;
- vdev->vidioc_s_fmt_cap = soc_camera_s_fmt_cap;
- vdev->vidioc_enum_input = soc_camera_enum_input;
- vdev->vidioc_g_input = soc_camera_g_input;
- vdev->vidioc_s_input = soc_camera_s_input;
- vdev->vidioc_s_std = soc_camera_s_std;
- vdev->vidioc_reqbufs = soc_camera_reqbufs;
- vdev->vidioc_try_fmt_cap = soc_camera_try_fmt_cap;
- vdev->vidioc_querybuf = soc_camera_querybuf;
- vdev->vidioc_qbuf = soc_camera_qbuf;
- vdev->vidioc_dqbuf = soc_camera_dqbuf;
- vdev->vidioc_streamon = soc_camera_streamon;
- vdev->vidioc_streamoff = soc_camera_streamoff;
- vdev->vidioc_queryctrl = soc_camera_queryctrl;
- vdev->vidioc_g_ctrl = soc_camera_g_ctrl;
- vdev->vidioc_s_ctrl = soc_camera_s_ctrl;
- vdev->vidioc_cropcap = soc_camera_cropcap;
- vdev->vidioc_g_crop = soc_camera_g_crop;
- vdev->vidioc_s_crop = soc_camera_s_crop;
- vdev->vidioc_g_chip_ident = soc_camera_g_chip_ident;
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- vdev->vidioc_g_register = soc_camera_g_register;
- vdev->vidioc_s_register = soc_camera_s_register;
-#endif
icd->current_fmt = &icd->formats[0];
err = video_register_device(vdev, VFL_TYPE_GRABBER, vdev->minor);
if (err < 0) {
- dev_err(vdev->dev, "video_register_device failed\n");
+ dev_err(vdev->parent, "video_register_device failed\n");
goto evidregd;
}
icd->vdev = vdev;