*
* Contact:
* Jinhyung Jo <jinhyung.jo@samsung.com>
+ * Sangho Park <sangho1206.park@samsung.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
+ * Boston, MA 02110-1301, USA.
*
* Contributors:
* - S-Core Co., Ltd
static unsigned debug;
+#define MARUCAM_MODULE_NAME "marucam"
+
#define marucam_err(fmt, arg...) \
- printk(KERN_ERR "[ERR]marucam[%s]: " fmt, __func__, ##arg)
+ printk(KERN_ERR "%s: error [%s:%d]: " fmt, MARUCAM_MODULE_NAME, \
+ __func__, __LINE__, ##arg)
#define marucam_warn(fmt, arg...) \
- printk(KERN_WARNING "[WARN]marucam[%s]: " fmt, __func__, ##arg)
+ printk(KERN_WARNING "%s: " fmt, MARUCAM_MODULE_NAME, ##arg)
#define marucam_info(fmt, arg...) \
- printk(KERN_INFO "[INFO]marucam[%s]: " fmt, __func__, ##arg)
+ printk(KERN_INFO "%s: " fmt, MARUCAM_MODULE_NAME, ##arg)
#define marucam_dbg(level, fmt, arg...) \
do { \
if (debug >= (level)) { \
- printk(KERN_DEBUG "[DBG]marucam[%s]: " fmt, \
- __func__, ##arg); \
+ printk(KERN_DEBUG "%s: [%s:%d]: " fmt, \
+ MARUCAM_MODULE_NAME, \
+ __func__, __LINE__, ##arg); \
} \
} while (0)
-#define MARUCAM_MODULE_NAME "marucam"
-
-#define MARUCAM_MAJOR_VERSION 0
-#define MARUCAM_MINOR_VERSION 25
-#define MARUCAM_RELEASE 1
+#define MARUCAM_MAJOR_VERSION 1
+#define MARUCAM_MINOR_VERSION 0
+#define MARUCAM_RELEASE 2
#define MARUCAM_VERSION \
KERNEL_VERSION(MARUCAM_MAJOR_VERSION, \
MARUCAM_MINOR_VERSION, MARUCAM_RELEASE)
MODULE_AUTHOR("Jinhyung Jo <jinhyung.jo@samsung.com>");
MODULE_LICENSE("GPL");
-#define DFL_WIDTH 640
-#define DFL_HEIGHT 480
-
/*
* Basic structures
*/
#define MARUCAM_OPEN 0x04
#define MARUCAM_CLOSE 0x08
#define MARUCAM_ISR 0x0C
-#define MARUCAM_START_PREVIEW 0x10
-#define MARUCAM_STOP_PREVIEW 0x14
-#define MARUCAM_S_PARAM 0x18
-#define MARUCAM_G_PARAM 0x1C
+#define MARUCAM_STREAMON 0x10
+#define MARUCAM_STREAMOFF 0x14
+#define MARUCAM_S_PARM 0x18
+#define MARUCAM_G_PARM 0x1C
#define MARUCAM_ENUM_FMT 0x20
#define MARUCAM_TRY_FMT 0x24
#define MARUCAM_S_FMT 0x28
#define MARUCAM_G_FMT 0x2C
-#define MARUCAM_QCTRL 0x30
+#define MARUCAM_QUERYCTRL 0x30
#define MARUCAM_S_CTRL 0x34
#define MARUCAM_G_CTRL 0x38
#define MARUCAM_ENUM_FSIZES 0x3C
#define MARUCAM_ENUM_FINTV 0x40
-#define MARUCAM_S_DATA 0x44
-#define MARUCAM_G_DATA 0x48
-#define MARUCAM_DTC 0x50
-#define MARUCAM_REQFRAME 0x54
+#define MARUCAM_REQFRAME 0x44
+#define MARUCAM_EXIT 0x48
enum marucam_opstate {
S_IDLE = 0,
S_RUNNING = 1
};
-
struct marucam_device {
struct v4l2_device v4l2_dev;
+ unsigned char dev_index;
spinlock_t slock;
struct mutex mlock;
enum marucam_opstate opstate;
struct pci_dev *pdev;
void __iomem *mmregs;
- resource_size_t io_base;
- resource_size_t io_size;
+ void __iomem *args;
resource_size_t mem_base;
resource_size_t mem_size;
+ resource_size_t iomem_size;
enum v4l2_buf_type type;
unsigned int width;
/*
* Use only one instance.
*/
-static struct marucam_device *marucam_instance;
+static struct marucam_device *marucam_instance[2];
/*
* The code below has been modified from 'videobuf_vmalloc.c'.
#define MAGIC_CHECK(is, should) \
do { \
if (unlikely((is) != (should))) { \
- marucam_err("Invalid the magic number:" \
+ marucam_err("invalid magic number:" \
" %x (expected %x)\n", is, should); \
BUG(); \
} \
mutex_lock(&q->vb_lock);
- if (q->streaming) {
+ if (q->streaming)
videobuf_queue_cancel(q);
- }
for (i = 0; i < VIDEO_MAX_FRAME; i++) {
- if (NULL == q->bufs[i]) {
+ if (NULL == q->bufs[i])
continue;
- }
- if (q->bufs[i]->map != map) {
+ if (q->bufs[i]->map != map)
continue;
- }
mem = q->bufs[i]->priv;
if (mem) {
vb = kzalloc(size + sizeof(*mem), GFP_KERNEL);
if (vb == NULL) {
- marucam_err("Failed to allocate the video buffer\n");
+ marucam_err("memory allocation failed for a video buffer\n");
return vb;
}
switch (vb->memory) {
case V4L2_MEMORY_MMAP:
if (!mem->mapped) {
- marucam_err("The memory is not mmapped.\n");
+ marucam_err("memory is not mapped\n");
return -EINVAL;
}
break;
default:
- marucam_err("Memory method currently unsupported.\n");
+ marucam_err("V4L2_MEMORY_MMAP only supported\n");
return -EINVAL;
}
map = kzalloc(sizeof(struct videobuf_mapping), GFP_KERNEL);
if (NULL == map) {
- marucam_err("Failed to allocate the video buffer map\n");
+ marucam_err("memory allocation failed for a video buffer mapping\n");
return -ENOMEM;
}
+ vma->vm_pgoff) >> PAGE_SHIFT,
pages, vma->vm_page_prot);
if (retval < 0) {
- marucam_err("Failed to remap the memory: %d\n", retval);
+ marucam_err("remap failed: %d\n", retval);
mem->mapped = 0;
mem = NULL;
kfree(map);
spin_lock_irqsave(q1->irqlock, flags);
if (dev->opstate != S_RUNNING) {
- marucam_err("The device state is not S_RUNNING\n");
+ marucam_err("state is not S_RUNNING\n");
spin_unlock_irqrestore(q1->irqlock, flags);
return;
}
if (list_empty(&dev->active)) {
- marucam_err("The active list is empty\n");
+ marucam_err("active list is empty\n");
spin_unlock_irqrestore(q1->irqlock, flags);
return;
}
buf = list_entry(dev->active.next, struct videobuf_buffer, queue);
if (!waitqueue_active(&buf->done)) {
- marucam_err("The list of wait queue is empty\n");
+ marucam_err("wait queue list is empty\n");
spin_unlock_irqrestore(q1->irqlock, flags);
return;
}
list_del(&buf->queue);
if (isr & 0x08) {
- marucam_err("The device state is invalid\n");
+ marucam_err("invalid state\n");
buf->state = 0xFF; /* invalid state */
} else {
- marucam_dbg(2, "The video buffer is filled\n");
+ marucam_dbg(2, "video buffer is filled\n");
buf->state = VIDEOBUF_DONE;
}
do_gettimeofday(&buf->ts);
isr = ioread32(dev->mmregs + MARUCAM_ISR);
if (!isr) {
- marucam_dbg(1, "This irq is not for this module\n");
+ marucam_dbg(1, "mismatched irq\n");
return IRQ_NONE;
}
static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_fmtdesc *f)
{
- int ret;
+ unsigned int ret;
struct marucam_device *dev = priv;
if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+ marucam_err("buf type is not V4L2_BUF_TYPE_VIDEO_CAPTURE\n");
return -EINVAL;
}
mutex_lock(&dev->mlock);
- iowrite32(0, dev->mmregs + MARUCAM_DTC);
- iowrite32(f->index, dev->mmregs + MARUCAM_S_DATA);
-
+ memset_io(dev->args, 0x00, dev->iomem_size);
+ memcpy_toio(dev->args, (const void *)f, sizeof(struct v4l2_fmtdesc));
iowrite32(0, dev->mmregs + MARUCAM_ENUM_FMT);
- ret = (int)ioread32(dev->mmregs + MARUCAM_ENUM_FMT);
+ ret = ioread32(dev->mmregs + MARUCAM_ENUM_FMT);
if (ret) {
+ if (ret != EINVAL) {
+ marucam_err("enum_fmt failed: ret(%d), idx(%u)\n",
+ ret, f->index);
+ }
mutex_unlock(&dev->mlock);
return -ret;
}
-
- f->index = ioread32(dev->mmregs + MARUCAM_G_DATA);
- f->flags = ioread32(dev->mmregs + MARUCAM_G_DATA);
- f->pixelformat = ioread32(dev->mmregs + MARUCAM_G_DATA);
- ioread32_rep(dev->mmregs + MARUCAM_G_DATA, f->description, 8);
-
+ memcpy_fromio((void *)f, dev->args, sizeof(struct v4l2_fmtdesc));
mutex_unlock(&dev->mlock);
+
return 0;
}
static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
- int ret;
+ unsigned int ret;
struct marucam_device *dev = priv;
+ struct v4l2_pix_format *pf = &f->fmt.pix;
+
+ if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+ marucam_err("buf type is not V4L2_BUF_TYPE_VIDEO_CAPTURE\n");
+ return -EINVAL;
+ }
mutex_lock(&dev->mlock);
- iowrite32(0, dev->mmregs + MARUCAM_DTC);
+ memset_io(dev->args, 0x00, dev->iomem_size);
+ memcpy_toio(dev->args, (const void *)pf, sizeof(struct v4l2_format));
iowrite32(0, dev->mmregs + MARUCAM_G_FMT);
- ret = (int)ioread32(dev->mmregs + MARUCAM_G_FMT);
+ ret = ioread32(dev->mmregs + MARUCAM_G_FMT);
if (ret) {
- marucam_err("Failed to get the format: %d\n", -ret);
+ marucam_err("g_fmt failed: ret(%d)\n", ret);
mutex_unlock(&dev->mlock);
return -ret;
}
+ memcpy_fromio((void *)pf, dev->args, sizeof(struct v4l2_format));
- f->fmt.pix.width = ioread32(dev->mmregs + MARUCAM_G_DATA);
- f->fmt.pix.height = ioread32(dev->mmregs + MARUCAM_G_DATA);
- f->fmt.pix.field = ioread32(dev->mmregs + MARUCAM_G_DATA);
- f->fmt.pix.pixelformat = ioread32(dev->mmregs + MARUCAM_G_DATA);
- f->fmt.pix.bytesperline = ioread32(dev->mmregs + MARUCAM_G_DATA);
- f->fmt.pix.sizeimage = ioread32(dev->mmregs + MARUCAM_G_DATA);
- f->fmt.pix.colorspace = ioread32(dev->mmregs + MARUCAM_G_DATA);
- f->fmt.pix.priv = ioread32(dev->mmregs + MARUCAM_G_DATA);
-
- dev->pixelformat = f->fmt.pix.pixelformat;
- dev->width = f->fmt.pix.width;
- dev->height = f->fmt.pix.height;
- dev->vb_vidq.field = f->fmt.pix.field;
+ dev->pixelformat = pf->pixelformat;
+ dev->width = pf->width;
+ dev->height = pf->height;
+ dev->vb_vidq.field = pf->field;
dev->type = f->type;
mutex_unlock(&dev->mlock);
static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
- int ret;
+ unsigned int ret;
struct marucam_device *dev = priv;
+ struct v4l2_pix_format *pf = &f->fmt.pix;
- mutex_lock(&dev->mlock);
- iowrite32(0, dev->mmregs + MARUCAM_DTC);
- iowrite32(f->fmt.pix.width, dev->mmregs + MARUCAM_S_DATA);
- iowrite32(f->fmt.pix.height, dev->mmregs + MARUCAM_S_DATA);
- iowrite32(f->fmt.pix.pixelformat, dev->mmregs + MARUCAM_S_DATA);
- iowrite32(f->fmt.pix.field, dev->mmregs + MARUCAM_S_DATA);
+ if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+ marucam_err("buf type is not V4L2_BUF_TYPE_VIDEO_CAPTURE\n");
+ return -EINVAL;
+ }
+ mutex_lock(&dev->mlock);
+ memset_io(dev->args, 0x00, dev->iomem_size);
+ memcpy_toio(dev->args, (const void *)pf, sizeof(struct v4l2_format));
iowrite32(0, dev->mmregs + MARUCAM_TRY_FMT);
- ret = (int)ioread32(dev->mmregs + MARUCAM_TRY_FMT);
+ ret = ioread32(dev->mmregs + MARUCAM_TRY_FMT);
if (ret) {
- marucam_err("Failed to check the format: %d\n", -ret);
+ marucam_err("try_fmt failed: ret(%d), wxh(%ux%u), pf(0x%x)\n",
+ ret, pf->width, pf->height,
+ pf->pixelformat);
mutex_unlock(&dev->mlock);
return -ret;
}
-
- f->fmt.pix.width = ioread32(dev->mmregs + MARUCAM_G_DATA);
- f->fmt.pix.height = ioread32(dev->mmregs + MARUCAM_G_DATA);
- f->fmt.pix.field = ioread32(dev->mmregs + MARUCAM_G_DATA);
- f->fmt.pix.pixelformat = ioread32(dev->mmregs + MARUCAM_G_DATA);
- f->fmt.pix.bytesperline = ioread32(dev->mmregs + MARUCAM_G_DATA);
- f->fmt.pix.sizeimage = ioread32(dev->mmregs + MARUCAM_G_DATA);
- f->fmt.pix.colorspace = ioread32(dev->mmregs + MARUCAM_G_DATA);
- f->fmt.pix.priv = ioread32(dev->mmregs + MARUCAM_G_DATA);
-
+ memcpy_fromio((void *)pf, dev->args, sizeof(struct v4l2_format));
mutex_unlock(&dev->mlock);
return 0;
}
static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
- int ret;
+ unsigned int ret;
struct marucam_device *dev = priv;
struct videobuf_queue *q2 = &dev->vb_vidq;
+ struct v4l2_pix_format *pf = &f->fmt.pix;
+
+ if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+ marucam_err("buf type is not V4L2_BUF_TYPE_VIDEO_CAPTURE\n");
+ return -EINVAL;
+ }
mutex_lock(&dev->mlock);
if (dev->opstate != S_IDLE) {
- marucam_err("The device state is not S_IDLE\n");
+ marucam_err("state is not S_IDLE\n");
mutex_unlock(&dev->mlock);
return -EBUSY;
}
mutex_lock(&q2->vb_lock);
if (videobuf_queue_is_busy(&dev->vb_vidq)) {
- marucam_err("The videobuf queue is busy\n");
+ marucam_err("videobuf queue is busy\n");
mutex_unlock(&q2->vb_lock);
mutex_unlock(&dev->mlock);
return -EBUSY;
}
mutex_unlock(&q2->vb_lock);
- iowrite32(0, dev->mmregs + MARUCAM_DTC);
- iowrite32(f->fmt.pix.width, dev->mmregs + MARUCAM_S_DATA);
- iowrite32(f->fmt.pix.height, dev->mmregs + MARUCAM_S_DATA);
- iowrite32(f->fmt.pix.pixelformat, dev->mmregs + MARUCAM_S_DATA);
- iowrite32(f->fmt.pix.field, dev->mmregs + MARUCAM_S_DATA);
+ memset_io(dev->args, 0x00, dev->iomem_size);
+ memcpy_toio(dev->args, (const void *)pf, sizeof(struct v4l2_format));
iowrite32(0, dev->mmregs + MARUCAM_S_FMT);
- ret = (int)ioread32(dev->mmregs + MARUCAM_S_FMT);
+ ret = ioread32(dev->mmregs + MARUCAM_S_FMT);
if (ret) {
- marucam_err("Failed to set the format: %d\n", -ret);
+ marucam_err("s_fmt failed: ret(%d), wxh(%ux%u), pf(0x%x)\n",
+ ret, pf->width, pf->height,
+ pf->pixelformat);
mutex_unlock(&dev->mlock);
return -ret;
}
+ memcpy_fromio((void *)pf, dev->args, sizeof(struct v4l2_format));
- f->fmt.pix.width = ioread32(dev->mmregs + MARUCAM_G_DATA);
- f->fmt.pix.height = ioread32(dev->mmregs + MARUCAM_G_DATA);
- f->fmt.pix.field = ioread32(dev->mmregs + MARUCAM_G_DATA);
- f->fmt.pix.pixelformat = ioread32(dev->mmregs + MARUCAM_G_DATA);
- f->fmt.pix.bytesperline = ioread32(dev->mmregs + MARUCAM_G_DATA);
- f->fmt.pix.sizeimage = ioread32(dev->mmregs + MARUCAM_G_DATA);
- f->fmt.pix.colorspace = ioread32(dev->mmregs + MARUCAM_G_DATA);
- f->fmt.pix.priv = ioread32(dev->mmregs + MARUCAM_G_DATA);
-
- dev->pixelformat = f->fmt.pix.pixelformat;
- dev->width = f->fmt.pix.width;
- dev->height = f->fmt.pix.height;
- dev->vb_vidq.field = f->fmt.pix.field;
+ dev->pixelformat = pf->pixelformat;
+ dev->width = pf->width;
+ dev->height = pf->height;
+ dev->vb_vidq.field = pf->field;
dev->type = f->type;
mutex_unlock(&dev->mlock);
ret = videobuf_reqbufs(&dev->vb_vidq, p);
if (ret) {
- marucam_err("Failed to request the video buffers\n");
+ marucam_err("%s failed: ret(%d), count(%u), type(%u), memory(%u)\n",
+ __func__, ret, p->count,
+ p->type, p->memory);
}
return ret;
ret = videobuf_querybuf(&dev->vb_vidq, p);
if (ret) {
- marucam_err("Failed to query the video buffer\n");
+ marucam_err("%s failed: ret(%d), idx(%u), type(%u), memory(%u)\n",
+ __func__, ret, p->index,
+ p->type, p->memory);
}
return ret;
ret = videobuf_qbuf(&dev->vb_vidq, p);
if (ret) {
- marucam_err("Failed to queue the video buffer\n");
+ marucam_err("%s failed: ret(%d), idx(%u), type(%u), memory(%u)\n",
+ __func__, ret, p->index,
+ p->type, p->memory);
}
return ret;
ret = videobuf_dqbuf(&dev->vb_vidq, p, file->f_flags & O_NONBLOCK);
if (ret) {
- marucam_err("Failed to dequeue the video buffer\n");
+ marucam_err("%s failed: ret(%d), idx(%u), type(%u), memory(%u)\n",
+ __func__, ret, p->index,
+ p->type, p->memory);
}
return ret;
static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
{
int ret = 0;
+ unsigned int dev_ret;
struct marucam_device *dev = priv;
if (dev->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+ marucam_err("buf type is not V4L2_BUF_TYPE_VIDEO_CAPTURE\n");
return -EINVAL;
}
if (i != dev->type) {
+ marucam_err("mismatched buf type\n");
return -EINVAL;
}
mutex_lock(&dev->mlock);
if (dev->opstate != S_IDLE) {
- marucam_err("The device state is not S_IDLE\n");
+ marucam_err("state is not S_IDLE\n");
mutex_unlock(&dev->mlock);
return -EBUSY;
}
- iowrite32(1, dev->mmregs + MARUCAM_START_PREVIEW);
- ret = (int)ioread32(dev->mmregs + MARUCAM_START_PREVIEW);
- if (ret) {
- marucam_err("Failed to start preview\n");
+ memset_io(dev->args, 0x00, dev->iomem_size);
+ iowrite32(0, dev->mmregs + MARUCAM_STREAMON);
+ dev_ret = ioread32(dev->mmregs + MARUCAM_STREAMON);
+ if (dev_ret) {
+ marucam_err("stream_on failed: ret(%d)\n", dev_ret);
mutex_unlock(&dev->mlock);
- return -ret;
+ return -dev_ret;
}
INIT_LIST_HEAD(&dev->active);
ret = videobuf_streamon(&dev->vb_vidq);
if (ret) {
- marucam_err("Failed to stream on the video buffer: %d\n", ret);
+ marucam_err("videobuf_streamon() failed: ret(%d)\n", ret);
mutex_unlock(&dev->mlock);
return ret;
}
static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
{
int ret = 0;
+ unsigned int dev_ret;
struct marucam_device *dev = priv;
if (dev->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+ marucam_err("buf type is not V4L2_BUF_TYPE_VIDEO_CAPTURE\n");
return -EINVAL;
}
if (i != dev->type) {
+ marucam_err("mismatched buf type\n");
return -EINVAL;
}
return 0;
}
- iowrite32(1, dev->mmregs + MARUCAM_STOP_PREVIEW);
- ret = (int)ioread32(dev->mmregs + MARUCAM_STOP_PREVIEW);
- if (ret) {
- marucam_err("Failed to stop preview\n");
+ memset_io(dev->args, 0x00, dev->iomem_size);
+ iowrite32(0, dev->mmregs + MARUCAM_STREAMOFF);
+ dev_ret = ioread32(dev->mmregs + MARUCAM_STREAMOFF);
+ if (dev_ret) {
+ marucam_err("stream_off failed: ret(%d)\n", dev_ret);
mutex_unlock(&dev->mlock);
- return -ret;
+ return -dev_ret;
}
dev->opstate = S_IDLE;
ret = videobuf_streamoff(&dev->vb_vidq);
- if (ret) {
- marucam_err("Failed to stream off the video buffer: %d\n",
- ret);
- }
+ if (ret)
+ marucam_err("videobuf_streamoff() failed: ret(%d)\n", ret);
INIT_LIST_HEAD(&dev->active);
mutex_unlock(&dev->mlock);
static int vidioc_enum_input(struct file *file, void *priv,
struct v4l2_input *inp)
{
- if (inp->index != 0) {
+ if (inp->index != 0)
return -EINVAL;
- }
inp->type = V4L2_INPUT_TYPE_CAMERA;
sprintf(inp->name, "MARU Virtual Camera %u", inp->index);
static int vidioc_queryctrl(struct file *file, void *priv,
struct v4l2_queryctrl *qc)
{
- int ret;
+ unsigned int ret;
struct marucam_device *dev = priv;
mutex_lock(&dev->mlock);
return -EINVAL;
}
- iowrite32(0, dev->mmregs + MARUCAM_DTC);
- iowrite32(qc->id, dev->mmregs + MARUCAM_S_DATA);
-
- iowrite32(0, dev->mmregs + MARUCAM_QCTRL);
- ret = (int)ioread32(dev->mmregs + MARUCAM_QCTRL);
+ memset_io(dev->args, 0x00, dev->iomem_size);
+ memcpy_toio(dev->args, (const void *)qc,
+ sizeof(struct v4l2_queryctrl));
+ iowrite32(0, dev->mmregs + MARUCAM_QUERYCTRL);
+ ret = ioread32(dev->mmregs + MARUCAM_QUERYCTRL);
if (ret) {
+ marucam_err("query_ctrl failed: ret(%d), id(%u)\n",
+ ret, qc->id);
mutex_unlock(&dev->mlock);
return -ret;
}
-
- qc->id = ioread32(dev->mmregs + MARUCAM_G_DATA);
- qc->minimum = ioread32(dev->mmregs + MARUCAM_G_DATA);
- qc->maximum = ioread32(dev->mmregs + MARUCAM_G_DATA);
- qc->step = ioread32(dev->mmregs + MARUCAM_G_DATA);
- qc->default_value = ioread32(dev->mmregs + MARUCAM_G_DATA);
- qc->flags = ioread32(dev->mmregs + MARUCAM_G_DATA);
- ioread32_rep(dev->mmregs + MARUCAM_G_DATA, qc->name, 8);
+ memcpy_fromio((void *)qc, dev->args,
+ sizeof(struct v4l2_queryctrl));
mutex_unlock(&dev->mlock);
return 0;
static int vidioc_g_ctrl(struct file *file, void *priv,
struct v4l2_control *ctrl)
{
- int ret;
+ unsigned int ret;
struct marucam_device *dev = priv;
mutex_lock(&dev->mlock);
- iowrite32(0, dev->mmregs + MARUCAM_DTC);
- iowrite32(ctrl->id, dev->mmregs + MARUCAM_S_DATA);
-
+ memset_io(dev->args, 0x00, dev->iomem_size);
+ memcpy_toio(dev->args, (const void *)ctrl,
+ sizeof(struct v4l2_control));
iowrite32(0, dev->mmregs + MARUCAM_G_CTRL);
- ret = (int)ioread32(dev->mmregs + MARUCAM_G_CTRL);
+ ret = ioread32(dev->mmregs + MARUCAM_G_CTRL);
if (ret) {
- marucam_err("Failed to get the control value\n");
+ marucam_err("g_ctrl failed: ret(%d), id(%u)\n",
+ ret, ctrl->id);
mutex_unlock(&dev->mlock);
return -ret;
}
-
- ctrl->value = ioread32(dev->mmregs + MARUCAM_G_DATA);
-
+ memcpy_fromio((void *)ctrl, dev->args,
+ sizeof(struct v4l2_control));
mutex_unlock(&dev->mlock);
return 0;
}
static int vidioc_s_ctrl(struct file *file, void *priv,
struct v4l2_control *ctrl)
{
- int ret;
+ unsigned int ret;
struct marucam_device *dev = priv;
mutex_lock(&dev->mlock);
- iowrite32(0, dev->mmregs + MARUCAM_DTC);
- iowrite32(ctrl->id, dev->mmregs + MARUCAM_S_DATA);
- iowrite32(ctrl->value, dev->mmregs + MARUCAM_S_DATA);
-
+ memset_io(dev->args, 0x00, dev->iomem_size);
+ memcpy_toio(dev->args, (const void *)ctrl,
+ sizeof(struct v4l2_control));
iowrite32(0, dev->mmregs + MARUCAM_S_CTRL);
- ret = (int)ioread32(dev->mmregs + MARUCAM_S_CTRL);
+ ret = ioread32(dev->mmregs + MARUCAM_S_CTRL);
if (ret) {
- marucam_err("Failed to set the control value\n");
+ marucam_err("s_ctrl failed: ret(%d), id(%u), val(%d)\n",
+ ret, ctrl->id, ctrl->value);
mutex_unlock(&dev->mlock);
return -ret;
}
-
+ memcpy_fromio((void *)ctrl, dev->args,
+ sizeof(struct v4l2_control));
mutex_unlock(&dev->mlock);
return 0;
}
static int vidioc_s_parm(struct file *file, void *priv,
struct v4l2_streamparm *parm)
{
- int ret;
+ unsigned int ret;
struct marucam_device *dev = priv;
struct v4l2_captureparm *cp = &parm->parm.capture;
if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+ marucam_err("buf type is not V4L2_BUF_TYPE_VIDEO_CAPTURE\n");
return -EINVAL;
}
mutex_lock(&dev->mlock);
- iowrite32(0, dev->mmregs + MARUCAM_DTC);
- iowrite32(cp->timeperframe.numerator, dev->mmregs + MARUCAM_S_DATA);
- iowrite32(cp->timeperframe.denominator, dev->mmregs + MARUCAM_S_DATA);
-
- iowrite32(0, dev->mmregs + MARUCAM_S_PARAM);
- ret = (int)ioread32(dev->mmregs + MARUCAM_S_PARAM);
+ memset_io(dev->args, 0x00, dev->iomem_size);
+ memcpy_toio(dev->args, (const void *)cp,
+ sizeof(struct v4l2_captureparm));
+ iowrite32(0, dev->mmregs + MARUCAM_S_PARM);
+ ret = ioread32(dev->mmregs + MARUCAM_S_PARM);
if (ret) {
- marucam_err("Failed to set the FPS\n");
+ marucam_err("s_parm failed: ret(%d)\n", ret);
mutex_unlock(&dev->mlock);
return -ret;
}
-
+ memcpy_fromio((void *)cp, dev->args,
+ sizeof(struct v4l2_captureparm));
mutex_unlock(&dev->mlock);
return 0;
}
static int vidioc_g_parm(struct file *file, void *priv,
struct v4l2_streamparm *parm)
{
- int ret;
+ unsigned int ret;
struct marucam_device *dev = priv;
struct v4l2_captureparm *cp = &parm->parm.capture;
if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+ marucam_err("buf type is not V4L2_BUF_TYPE_VIDEO_CAPTURE\n");
return -EINVAL;
}
mutex_lock(&dev->mlock);
- iowrite32(0, dev->mmregs + MARUCAM_DTC);
- iowrite32(0, dev->mmregs + MARUCAM_G_PARAM);
- ret = (int)ioread32(dev->mmregs + MARUCAM_G_PARAM);
+ memset_io(dev->args, 0x00, dev->iomem_size);
+ memcpy_toio(dev->args, (const void *)cp,
+ sizeof(struct v4l2_captureparm));
+ iowrite32(0, dev->mmregs + MARUCAM_G_PARM);
+ ret = ioread32(dev->mmregs + MARUCAM_G_PARM);
if (ret) {
- marucam_err("Failed to get the FPS\n");
+ marucam_err("g_parm failed: ret(%d)\n", ret);
mutex_unlock(&dev->mlock);
return -ret;
}
-
- cp->capability = ioread32(dev->mmregs + MARUCAM_G_DATA);
- cp->timeperframe.numerator = ioread32(dev->mmregs + MARUCAM_G_DATA);
- cp->timeperframe.denominator = ioread32(dev->mmregs + MARUCAM_G_DATA);
-
+ memcpy_fromio((void *)cp, dev->args,
+ sizeof(struct v4l2_captureparm));
mutex_unlock(&dev->mlock);
return 0;
}
static int vidioc_enum_framesizes(struct file *file, void *priv,
struct v4l2_frmsizeenum *fsize)
{
- int ret;
+ unsigned int ret;
struct marucam_device *dev = priv;
mutex_lock(&dev->mlock);
- iowrite32(0, dev->mmregs + MARUCAM_DTC);
- iowrite32(fsize->index, dev->mmregs + MARUCAM_S_DATA);
- iowrite32(fsize->pixel_format, dev->mmregs + MARUCAM_S_DATA);
-
+ memset_io(dev->args, 0x00, dev->iomem_size);
+ memcpy_toio(dev->args, (const void *)fsize,
+ sizeof(struct v4l2_frmsizeenum));
iowrite32(0, dev->mmregs + MARUCAM_ENUM_FSIZES);
- ret = (int)ioread32(dev->mmregs + MARUCAM_ENUM_FSIZES);
+ ret = ioread32(dev->mmregs + MARUCAM_ENUM_FSIZES);
if (ret) {
+ if (ret != EINVAL) {
+ marucam_err("enum_framesizes failed: %d, index(%u), pix(%u)\n",
+ ret, fsize->index, fsize->pixel_format);
+ }
mutex_unlock(&dev->mlock);
return -ret;
}
-
- fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
- fsize->discrete.width = ioread32(dev->mmregs + MARUCAM_G_DATA);
- fsize->discrete.height = ioread32(dev->mmregs + MARUCAM_G_DATA);
-
+ memcpy_fromio((void *)fsize, dev->args,
+ sizeof(struct v4l2_frmsizeenum));
mutex_unlock(&dev->mlock);
return 0;
}
static int vidioc_enum_frameintervals(struct file *file, void *priv,
struct v4l2_frmivalenum *fival)
{
- int ret;
+ unsigned int ret;
struct marucam_device *dev = priv;
mutex_lock(&dev->mlock);
- iowrite32(0, dev->mmregs + MARUCAM_DTC);
- iowrite32(fival->index, dev->mmregs + MARUCAM_S_DATA);
- iowrite32(fival->pixel_format, dev->mmregs + MARUCAM_S_DATA);
- iowrite32(fival->width, dev->mmregs + MARUCAM_S_DATA);
- iowrite32(fival->height, dev->mmregs + MARUCAM_S_DATA);
-
+ memset_io(dev->args, 0x00, dev->iomem_size);
+ memcpy_toio(dev->args, (const void *)fival,
+ sizeof(struct v4l2_frmivalenum));
iowrite32(0, dev->mmregs + MARUCAM_ENUM_FINTV);
- ret = (int)ioread32(dev->mmregs + MARUCAM_ENUM_FINTV);
+ ret = ioread32(dev->mmregs + MARUCAM_ENUM_FINTV);
if (ret) {
+ if (ret != EINVAL) {
+ marucam_err("%s failed: ret(%d), idx(%u), pf(%u), %ux%u\n",
+ __func__, ret, fival->index,
+ fival->pixel_format, fival->width,
+ fival->height);
+ }
mutex_unlock(&dev->mlock);
return -ret;
}
-
- fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
- fival->discrete.numerator = ioread32(dev->mmregs + MARUCAM_G_DATA);
- fival->discrete.denominator = ioread32(dev->mmregs + MARUCAM_G_DATA);
-
+ memcpy_fromio((void *)fival, dev->args,
+ sizeof(struct v4l2_frmivalenum));
mutex_unlock(&dev->mlock);
return 0;
}
*size = get_image_size(dev);
- if (*count > 2) {
+ if (*count > 2)
*count = 2;
- } else if (*count == 0) {
+ else if (*count == 0)
*count = 2;
- }
marucam_dbg(1, "count=%d, size=%d\n", *count, *size);
vb->size = get_image_size(dev);
if (0 != vb->baddr && vb->bsize < vb->size) {
- marucam_err("The video buffer size is invalid\n");
+ marucam_err("invalid buffer size\n");
return -EINVAL;
}
if (vb->state == VIDEOBUF_NEEDS_INIT) {
rc = videobuf_iolock(vq, vb, NULL);
if (rc < 0) {
- marucam_err("Failed to videobuf_iolock\n");
+ marucam_err("videobuf_iolock() failed: ret(%d)\n", rc);
vb->state = VIDEOBUF_NEEDS_INIT;
return rc;
}
static int marucam_open(struct file *file)
{
int ret;
+ unsigned int dev_ret;
struct marucam_device *dev = video_drvdata(file);
file->private_data = dev;
mutex_lock(&dev->mlock);
if (dev->in_use) {
- marucam_err("The device has been already opened\n");
+ marucam_err("already opened\n");
mutex_unlock(&dev->mlock);
return -EBUSY;
}
dev->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- dev->pixelformat = V4L2_PIX_FMT_YUYV;
- dev->width = DFL_WIDTH;
- dev->height = DFL_HEIGHT;
+ dev->pixelformat = 0;
+ dev->width = 0;
+ dev->height = 0;
ret = request_irq(dev->pdev->irq, marucam_irq_handler,
IRQF_SHARED, MARUCAM_MODULE_NAME, dev);
if (ret) {
- marucam_err("Failed to request the irq: irq(#%d)\n",
- dev->pdev->irq);
+ marucam_err("request_irq() failed: ret(%d), irq(#%d)\n",
+ ret, dev->pdev->irq);
mutex_unlock(&dev->mlock);
return ret;
}
V4L2_FIELD_NONE, sizeof(struct videobuf_buffer),
dev, NULL);
+ memset_io(dev->args, 0x00, dev->iomem_size);
iowrite32(0, dev->mmregs + MARUCAM_OPEN);
- ret = (int)ioread32(dev->mmregs + MARUCAM_OPEN);
- if (ret) {
- marucam_err("Failed to open the device\n");
+ dev_ret = ioread32(dev->mmregs + MARUCAM_OPEN);
+ if (dev_ret) {
+ marucam_err("device open failed: ret(%d)\n", dev_ret);
free_irq(dev->pdev->irq, dev);
mutex_unlock(&dev->mlock);
- return -ret;
+ return -dev_ret;
}
dev->in_use = 1;
mutex_unlock(&dev->mlock);
return 0;
+
}
static int marucam_close(struct file *file)
{
- int ret;
+ unsigned int ret;
struct marucam_device *dev = file->private_data;
mutex_lock(&dev->mlock);
if (dev->opstate == S_RUNNING) {
- marucam_err("The device has been terminated unexpectedly.\n");
- iowrite32(1, dev->mmregs + MARUCAM_STOP_PREVIEW);
- ret = (int)ioread32(dev->mmregs + MARUCAM_STOP_PREVIEW);
+ marucam_err("unexpectedly terminated\n");
+ iowrite32(0, dev->mmregs + MARUCAM_STREAMOFF);
+ ret = ioread32(dev->mmregs + MARUCAM_STREAMOFF);
if (ret) {
- marucam_err("Failed to stop the preview\n");
+ marucam_err("stream_off failed: ret(%d)\n", ret);
mutex_unlock(&dev->mlock);
return -ret;
}
free_irq(dev->pdev->irq, dev);
+ memset_io(dev->args, 0x00, dev->iomem_size);
iowrite32(0, dev->mmregs + MARUCAM_CLOSE);
- ret = (int)ioread32(dev->mmregs + MARUCAM_CLOSE);
+ ret = ioread32(dev->mmregs + MARUCAM_CLOSE);
if (ret) {
- marucam_err("Failed to close the device\n");
+ marucam_err("close failed: ret(%d)\n", ret);
mutex_unlock(&dev->mlock);
return -ret;
}
struct videobuf_queue *q3 = &poll_dev->vb_vidq;
struct videobuf_buffer *vbuf = NULL;
- if (q3->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+ if (q3->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
return POLLERR;
- }
mutex_lock(&q3->vb_lock);
if (q3->streaming) {
}
}
if (!vbuf) {
- marucam_err("The video buffer list is empty\n");
+ marucam_err("video buffer list is empty\n");
rval = POLLERR;
}
Initialization and module stuff
------------------------------------------------------------------*/
-DEFINE_PCI_DEVICE_TABLE(marucam_pci_id_tbl) = {
+static const struct pci_device_id marucam_pci_id_tbl[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_TIZEN, PCI_DEVICE_ID_VIRTUAL_CAMERA) },
{}
};
debug = MARUCAM_DEBUG_LEVEL;
- if (marucam_instance != NULL) {
- marucam_err("Only one device allowed\n");
+ if (!pci_resource_len(pdev, 0)) {
+ marucam_info("No available device\n");
+ return -ENODEV;
+ }
+
+ if (marucam_instance[0] && marucam_instance[1]) {
+ marucam_err("Two devices already exists\n");
return -EBUSY;
}
dev = kzalloc(sizeof(struct marucam_device), GFP_KERNEL);
if (!dev) {
- marucam_err("kzalloc() failed\n");
+ marucam_err("Memory allocation failed for a marucam device\n");
return -ENOMEM;
}
- marucam_instance = dev;
- ret_val = v4l2_device_register(&pdev->dev, &dev->v4l2_dev);
+ ret_val = pci_enable_device(pdev);
if (ret_val) {
+ marucam_err("pci_enable_device failed\n");
kfree(dev);
- dev = NULL;
- marucam_instance = NULL;
return ret_val;
}
- INIT_LIST_HEAD(&dev->active);
- spin_lock_init(&dev->slock);
- mutex_init(&dev->mlock);
- dev->opstate = S_IDLE;
-
- dev->pdev = pdev;
+ dev->mem_base = pci_resource_start(pdev, 0);
+ dev->mem_size = pci_resource_len(pdev, 0);
- ret_val = -ENOMEM;
- dev->vfd = video_device_alloc();
- if (!dev->vfd) {
- marucam_err("video_device_alloc() failed!!\n");
- v4l2_device_unregister(&dev->v4l2_dev);
+ if (pci_request_region(pdev, 0, MARUCAM_MODULE_NAME)) {
+ marucam_err("request region failed for 0 bar\n");
+ pci_disable_device(pdev);
kfree(dev);
- dev = NULL;
- marucam_instance = NULL;
- return ret_val;
+ return -EBUSY;
}
- memcpy(dev->vfd, &marucam_video_dev, sizeof(marucam_video_dev));
-
- dev->vfd->dev_parent = &dev->pdev->dev;
- dev->vfd->v4l2_dev = &dev->v4l2_dev;
-
- ret_val = pci_enable_device(dev->pdev);
- if (ret_val) {
- marucam_err("pci_enable_device failed!!\n");
- video_device_release(dev->vfd);
- v4l2_device_unregister(&dev->v4l2_dev);
+ if (pci_request_region(pdev, 1, MARUCAM_MODULE_NAME)) {
+ marucam_err("request region failed for 1 bar\n");
+ pci_release_region(pdev, 0);
+ pci_disable_device(pdev);
kfree(dev);
- dev = NULL;
- marucam_instance = NULL;
- return ret_val;
+ return -EBUSY;
}
- pci_set_master(dev->pdev);
-
- ret_val = -EIO;
- dev->mem_base = pci_resource_start(dev->pdev, 0);
- dev->mem_size = pci_resource_len(dev->pdev, 0);
- if (!dev->mem_base) {
- marucam_err("pci_resource_start failed!!\n");
- pci_disable_device(dev->pdev);
- video_device_release(dev->vfd);
- v4l2_device_unregister(&dev->v4l2_dev);
+ if (pci_request_region(pdev, 2, MARUCAM_MODULE_NAME)) {
+ marucam_err("request region failed for 2 bar\n");
+ pci_release_region(pdev, 0);
+ pci_release_region(pdev, 1);
+ pci_disable_device(pdev);
kfree(dev);
- dev = NULL;
- marucam_instance = NULL;
- return ret_val;
+ return -EBUSY;
}
- if (!request_mem_region(dev->mem_base, dev->mem_size,
- MARUCAM_MODULE_NAME)) {
- marucam_err("request_mem_region(mem) failed!!\n");
- pci_disable_device(dev->pdev);
- video_device_release(dev->vfd);
- v4l2_device_unregister(&dev->v4l2_dev);
+ dev->args = pci_ioremap_bar(pdev, 1);
+ if (!dev->args) {
+ marucam_err("pci_ioremap_bar failed for 1 bar\n");
+ pci_release_region(pdev, 0);
+ pci_release_region(pdev, 1);
+ pci_release_region(pdev, 2);
+ pci_disable_device(pdev);
kfree(dev);
- dev = NULL;
- marucam_instance = NULL;
- return ret_val;
+ return -EIO;
}
+ dev->iomem_size = pci_resource_len(pdev, 1);
- dev->io_base = pci_resource_start(dev->pdev, 1);
- dev->io_size = pci_resource_len(dev->pdev, 1);
-
- if (!dev->io_base) {
- marucam_err("pci_resource_start failed!!\n");
- release_mem_region(dev->mem_base, dev->mem_size);
- pci_disable_device(dev->pdev);
- video_device_release(dev->vfd);
- v4l2_device_unregister(&dev->v4l2_dev);
+ dev->mmregs = pci_ioremap_bar(pdev, 2);
+ if (!dev->mmregs) {
+ marucam_err("pci_ioremap_bar failed for 2 bar\n");
+ iounmap(dev->args);
+ pci_release_region(pdev, 0);
+ pci_release_region(pdev, 1);
+ pci_release_region(pdev, 2);
+ pci_disable_device(pdev);
kfree(dev);
- dev = NULL;
- marucam_instance = NULL;
- return ret_val;
+ return -EIO;
}
- if (!request_mem_region(dev->io_base, dev->io_size,
- MARUCAM_MODULE_NAME)) {
- marucam_err("request_mem_region(io) failed!!\n");
- release_mem_region(dev->mem_base, dev->mem_size);
- pci_disable_device(dev->pdev);
- video_device_release(dev->vfd);
- v4l2_device_unregister(&dev->v4l2_dev);
+ dev->dev_index = ioread32(dev->mmregs + MARUCAM_INIT);
+ marucam_info("device index is %d", dev->dev_index);
+ pci_set_master(pdev);
+ pci_set_drvdata(pdev, dev);
+
+ ret_val = v4l2_device_register(&pdev->dev, &dev->v4l2_dev);
+ if (ret_val < 0) {
+ marucam_err("v4l2_device_register() failed: %d\n", ret_val);
+ iounmap(dev->args);
+ iounmap(dev->mmregs);
+ pci_release_region(pdev, 0);
+ pci_release_region(pdev, 1);
+ pci_release_region(pdev, 2);
+ pci_disable_device(pdev);
kfree(dev);
- dev = NULL;
- marucam_instance = NULL;
return ret_val;
}
- dev->mmregs = ioremap(dev->io_base, dev->io_size);
- if (!dev->mmregs) {
- marucam_err("ioremap failed!!\n");
- release_mem_region(dev->io_base, dev->io_size);
- release_mem_region(dev->mem_base, dev->mem_size);
- pci_disable_device(dev->pdev);
- video_device_release(dev->vfd);
+ dev->vfd = video_device_alloc();
+ if (dev->vfd == NULL) {
v4l2_device_unregister(&dev->v4l2_dev);
+ iounmap(dev->args);
+ iounmap(dev->mmregs);
+ pci_release_region(pdev, 0);
+ pci_release_region(pdev, 1);
+ pci_release_region(pdev, 2);
+ pci_disable_device(pdev);
kfree(dev);
- dev = NULL;
- marucam_instance = NULL;
- return ret_val;
+ return -ENOMEM;
}
- ret_val = video_register_device(dev->vfd, VFL_TYPE_GRABBER, 0);
+ memcpy(dev->vfd, &marucam_video_dev, sizeof(marucam_video_dev));
+ dev->vfd->dev_parent = &pdev->dev;
+ dev->vfd->v4l2_dev = &dev->v4l2_dev;
+
+ ret_val = video_register_device(dev->vfd,
+ VFL_TYPE_GRABBER,
+ dev->dev_index);
if (ret_val < 0) {
- marucam_err("video_register_device failed!!\n");
- iounmap(dev->mmregs);
- release_mem_region(dev->io_base, dev->io_size);
- release_mem_region(dev->mem_base, dev->mem_size);
- pci_disable_device(dev->pdev);
+ marucam_err("video_register_device() failed: %d\n", ret_val);
video_device_release(dev->vfd);
v4l2_device_unregister(&dev->v4l2_dev);
+ iounmap(dev->args);
+ iounmap(dev->mmregs);
+ pci_release_region(pdev, 0);
+ pci_release_region(pdev, 1);
+ pci_release_region(pdev, 2);
+ pci_disable_device(pdev);
kfree(dev);
- dev = NULL;
- marucam_instance = NULL;
return ret_val;
}
video_set_drvdata(dev->vfd, dev);
- pci_set_drvdata(pdev, dev);
+
+ INIT_LIST_HEAD(&dev->active);
+ spin_lock_init(&dev->slock);
+ mutex_init(&dev->mlock);
+ dev->opstate = S_IDLE;
+ dev->pdev = pdev;
+
snprintf(dev->vfd->name, sizeof(dev->vfd->name), "%s (%i)",
marucam_video_dev.name, dev->vfd->num);
- marucam_info("V4L2 device registerd as /dev/video%d\n", dev->vfd->num);
+ marucam_instance[dev->dev_index] = dev;
+ marucam_info("Maru Camera(%u.%u.%u) device is registerd as /dev/video%d\n",
+ (MARUCAM_VERSION >> 16) & 0xFF,
+ (MARUCAM_VERSION >> 8) & 0xFF,
+ MARUCAM_VERSION & 0xFF,
+ dev->vfd->num);
return 0;
}
static void marucam_pci_removedev(struct pci_dev *pdev)
{
+ unsigned char dev_index;
struct marucam_device *dev = pci_get_drvdata(pdev);
if (dev == NULL) {
- marucam_warn("pci_remove on unknown pdev %p.\n", pdev);
- return ;
+ marucam_warn("pci_remove on unknown pdev %p\n", pdev);
+ return;
}
+ dev_index = dev->dev_index;
video_unregister_device(dev->vfd);
-
- if (dev->mmregs) {
- iounmap(dev->mmregs);
- dev->mmregs = 0;
- }
-
- if (dev->io_base) {
- release_mem_region(dev->io_base, dev->io_size);
- dev->io_base = 0;
- }
- if (dev->mem_base) {
- release_mem_region(dev->mem_base, dev->mem_size);
- dev->mem_base = 0;
- }
- pci_disable_device(dev->pdev);
v4l2_device_unregister(&dev->v4l2_dev);
+ iounmap(dev->args);
+ iounmap(dev->mmregs);
+ pci_release_region(dev->pdev, 0);
+ pci_release_region(dev->pdev, 1);
+ pci_release_region(dev->pdev, 2);
+ pci_disable_device(dev->pdev);
+
+ memset(dev, 0x00, sizeof(struct marucam_device));
kfree(dev);
dev = NULL;
- marucam_instance = NULL;
+ marucam_instance[dev_index] = NULL;
}
static struct pci_driver marucam_pci_driver = {
static int __init marucam_init(void)
{
- int retv = 0;
-
- retv = pci_register_driver(&marucam_pci_driver);
- if (retv < 0) {
- marucam_info("Error %d while loading marucam driver\n", retv);
- return retv;
- }
-
- marucam_info("MARU Camera Driver ver %u.%u.%u successfully loaded.\n",
- (MARUCAM_VERSION >> 16) & 0xFF, (MARUCAM_VERSION >> 8) & 0xFF,
- MARUCAM_VERSION & 0xFF);
-
- return retv;
+ return pci_register_driver(&marucam_pci_driver);
}
static void __exit marucam_exit(void)