* Copyright (c) 2011 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
*
* Contact:
- * Hyunjun Son <hj79.son@samsung.com>
- * GiWoong Kim <giwoong.kim@samsung.com>
- * YeongKyoon Lee <yeongkyoon.lee@samsung.com>
+ * Jinhyung Jo <jinhyung.jo@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.
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
*
* Contributors:
* - S-Core Co., Ltd
#include <media/v4l2-common.h>
#include <media/v4l2-ioctl.h>
-#define SVO_DRIVER_MAJORVERSION 0
-#define SVO_DRIVER_MINORVERSION 1
+#define SVO_DRIVER_MAJORVERSION 0
+#define SVO_DRIVER_MINORVERSION 2
enum {
OVERLAY_POWER = 0x00,
- OVERLAY_POSITION = 0x04, // left top position
- OVERLAY_SIZE = 0x08, // width and height
+ OVERLAY_POSITION = 0x04, /* left & top */
+ OVERLAY_SIZE = 0x08, /* width & height */
};
-static struct pci_device_id svo_pci_tbl[] = {
- {
- .vendor = PCI_VENDOR_ID_TIZEN,
- .device = 0x1010,
- .subvendor = PCI_ANY_ID,
- .subdevice = PCI_ANY_ID,
- }
-};
+DEFINE_PCI_DEVICE_TABLE(svo_pci_tbl) = {
+ { PCI_DEVICE(PCI_VENDOR_ID_TIZEN, PCI_DEVICE_ID_VIRTUAL_OVERLAY) } };
struct svo {
- struct pci_dev *pci_dev; /* pci device */
+ /* pci device */
+ struct pci_dev *pci_dev;
- struct video_device *video_dev0; /* video device parameters */
- struct video_device *video_dev1; /* video device parameters */
+ /* video device parameters */
+ struct video_device *video_dev0;
+ struct video_device *video_dev1;
- resource_size_t mem_start;
- resource_size_t reg_start;
+ resource_size_t mem_start;
+ resource_size_t reg_start;
- resource_size_t mem_size;
- resource_size_t reg_size;
+ resource_size_t mem_size;
+ resource_size_t reg_size;
- unsigned char __iomem *svo_mmreg; /* svo: memory mapped registers */
+ /* svo: memory mapped registers */
+ unsigned char __iomem *svo_mmreg;
- unsigned long in_use0; /* set to 1 if the device is in use */
- unsigned long in_use1; /* set to 1 if the device is in use */
+ /* set to 1 if the device is in use */
+ unsigned long in_use0;
+ unsigned long in_use1;
- struct v4l2_rect w0, w1; /* overlaid rect */
+ /* overlaid rect */
+ struct v4l2_rect w0, w1;
};
-/* driver structure - only one possible */
+/*
+ * driver structure - only one possible
+ */
static struct svo svo;
-/****************************************************************************/
-/* virtual register access helper */
-/****************************************************************************/
+/*
+ * virtual register access helper
+ */
+static void overlay_power(int num, int onoff)
+{
+ unsigned int ret;
-static void overlay_power(int num, int onoff) {
- writel(onoff, svo.svo_mmreg + num * svo.reg_size / 2 + OVERLAY_POWER);
+ ret = readl(svo.svo_mmreg + num * svo.reg_size / 2 + OVERLAY_POWER);
+ if (ret != onoff) {
+ writel(onoff, svo.svo_mmreg
+ + num * svo.reg_size / 2 + OVERLAY_POWER);
+ }
}
-/****************************************************************************/
-/* svo ioctls */
-/****************************************************************************/
-
+/*
+ * svo ioctls
+ */
static int svo_querycap(struct file *file, void *fh,
struct v4l2_capability *cap)
{
static int svo0_g_fmt_vid_overlay(struct file *file, void *priv,
struct v4l2_format *f)
{
+ unsigned int ret = 0;
+
if (f->type != V4L2_BUF_TYPE_VIDEO_OVERLAY)
return -EINVAL;
+ ret = readl(svo.svo_mmreg + OVERLAY_POSITION);
+ svo.w0.left = ret & 0xFFFF;
+ svo.w0.top = (ret >> 16) & 0xFFFF;
+ ret = readl(svo.svo_mmreg + OVERLAY_SIZE);
+ svo.w0.width = ret & 0xFFFF;
+ svo.w0.height = (ret >> 16) & 0xFFFF;
+
f->fmt.win.w.left = svo.w0.left;
f->fmt.win.w.top = svo.w0.top;
f->fmt.win.w.width = svo.w0.width;
static int svo1_g_fmt_vid_overlay(struct file *file, void *priv,
struct v4l2_format *f)
{
+ unsigned int ret = 0;
+
if (f->type != V4L2_BUF_TYPE_VIDEO_OVERLAY)
return -EINVAL;
+ ret = readl(svo.svo_mmreg + svo.reg_size / 2 + OVERLAY_POSITION);
+ svo.w1.left = ret & 0xFFFF;
+ svo.w1.top = (ret >> 16) & 0xFFFF;
+ ret = readl(svo.svo_mmreg + svo.reg_size / 2 + OVERLAY_SIZE);
+ svo.w1.width = ret & 0xFFFF;
+ svo.w1.height = (ret >> 16) & 0xFFFF;
+
f->fmt.win.w.left = svo.w1.left;
f->fmt.win.w.top = svo.w1.top;
f->fmt.win.w.width = svo.w1.width;
static int svo0_s_fmt_vid_overlay(struct file *file, void *priv,
struct v4l2_format *f)
{
+ unsigned int arg;
+
if (f->type != V4L2_BUF_TYPE_VIDEO_OVERLAY)
return -EINVAL;
svo.w0.width = f->fmt.win.w.width;
svo.w0.height = f->fmt.win.w.height;
- writel(svo.w0.left | svo.w0.top << 16, svo.svo_mmreg + OVERLAY_POSITION);
- writel(svo.w0.width | svo.w0.height << 16, svo.svo_mmreg + OVERLAY_SIZE);
+ arg = svo.w0.left | (svo.w0.top << 16);
+ writel(arg, svo.svo_mmreg + OVERLAY_POSITION);
+ arg = svo.w0.width | (svo.w0.height << 16);
+ writel(arg, svo.svo_mmreg + OVERLAY_SIZE);
return 0;
}
static int svo1_s_fmt_vid_overlay(struct file *file, void *priv,
struct v4l2_format *f)
{
+ unsigned int arg;
+
if (f->type != V4L2_BUF_TYPE_VIDEO_OVERLAY)
return -EINVAL;
svo.w1.width = f->fmt.win.w.width;
svo.w1.height = f->fmt.win.w.height;
- writel(svo.w1.left | svo.w1.top << 16, svo.svo_mmreg + svo.reg_size / 2 + OVERLAY_POSITION);
- writel(svo.w1.width | svo.w1.height << 16, svo.svo_mmreg + svo.reg_size / 2 + OVERLAY_SIZE);
+ arg = svo.w1.left | (svo.w1.top << 16);
+ writel(arg, svo.svo_mmreg + svo.reg_size / 2 + OVERLAY_POSITION);
+ arg = svo.w1.width | (svo.w1.height << 16);
+ writel(arg, svo.svo_mmreg + svo.reg_size / 2 + OVERLAY_SIZE);
return 0;
}
return 0;
}
-static int svo0_overlay (struct file *file, void *fh, unsigned int i)
+static int svo0_overlay(struct file *file, void *fh, unsigned int i)
{
overlay_power(0, i);
return 0;
}
-static int svo1_overlay (struct file *file, void *fh, unsigned int i)
+static int svo1_overlay(struct file *file, void *fh, unsigned int i)
{
overlay_power(1, i);
return 0;
}
-/****************************************************************************/
-/* File operations */
-/****************************************************************************/
+/*
+ * File operations
+ */
static int svo0_open(struct file *file)
{
if (size > svo.mem_size)
return -EINVAL;
- if (remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, size, PAGE_SHARED))
+ if (remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
+ size, PAGE_SHARED))
return -EAGAIN;
-
+
vma->vm_ops = &svo_vm_ops;
vma->vm_flags &= ~VM_IO; /* not I/O memory */
vma->vm_flags |= VM_RESERVED; /* avoid to swap out this VMA */
}
static const struct v4l2_ioctl_ops svo0_ioctl_ops = {
- .vidioc_querycap = svo_querycap,
- .vidioc_g_fmt_vid_overlay = svo0_g_fmt_vid_overlay,
- .vidioc_s_fmt_vid_overlay = svo0_s_fmt_vid_overlay,
- .vidioc_reqbufs = svo_reqbufs,
- .vidioc_querybuf = svo0_querybuf,
- .vidioc_overlay = svo0_overlay,
+ .vidioc_querycap = svo_querycap,
+ .vidioc_g_fmt_vid_overlay = svo0_g_fmt_vid_overlay,
+ .vidioc_s_fmt_vid_overlay = svo0_s_fmt_vid_overlay,
+ .vidioc_reqbufs = svo_reqbufs,
+ .vidioc_querybuf = svo0_querybuf,
+ .vidioc_overlay = svo0_overlay,
};
static const struct v4l2_ioctl_ops svo1_ioctl_ops = {
- .vidioc_querycap = svo_querycap,
- .vidioc_g_fmt_vid_overlay = svo1_g_fmt_vid_overlay,
- .vidioc_s_fmt_vid_overlay = svo1_s_fmt_vid_overlay,
- .vidioc_reqbufs = svo_reqbufs,
- .vidioc_querybuf = svo1_querybuf,
- .vidioc_overlay = svo1_overlay,
+ .vidioc_querycap = svo_querycap,
+ .vidioc_g_fmt_vid_overlay = svo1_g_fmt_vid_overlay,
+ .vidioc_s_fmt_vid_overlay = svo1_s_fmt_vid_overlay,
+ .vidioc_reqbufs = svo_reqbufs,
+ .vidioc_querybuf = svo1_querybuf,
+ .vidioc_overlay = svo1_overlay,
};
static const struct v4l2_file_operations svo0_fops = {
static struct video_device svo0_template = {
.name = "svo0",
.fops = &svo0_fops,
- .ioctl_ops = &svo0_ioctl_ops,
+ .ioctl_ops = &svo0_ioctl_ops,
.release = video_device_release,
.minor = -1,
};
static struct video_device svo1_template = {
.name = "svo1",
.fops = &svo1_fops,
- .ioctl_ops = &svo1_ioctl_ops,
+ .ioctl_ops = &svo1_ioctl_ops,
.release = video_device_release,
.minor = -1,
};
-/* /dev/videoX registration number */
-static int video_nr = -1;
-module_param(video_nr, int, 0444);
-MODULE_PARM_DESC(video_nr, "video device to register (0=/dev/video0, etc)");
-
static int __devinit svo_initdev(struct pci_dev *pci_dev,
const struct pci_device_id *ent)
{
ret = -EIO;
- if ((ret = pci_enable_device(svo.pci_dev))) {
+ ret = pci_enable_device(svo.pci_dev);
+ if (ret) {
printk(KERN_ERR "svo: pci_enable_device failed\n");
goto outnotdev;
}
- svo.mem_start = pci_resource_start(svo.pci_dev,0);
+ svo.mem_start = pci_resource_start(svo.pci_dev, 0);
svo.mem_size = pci_resource_len(svo.pci_dev, 0);
if (!svo.mem_start) {
printk(KERN_ERR "svo: svo has no device base address\n");
printk(KERN_ERR "svo: request_mem_region failed\n");
goto outregions;
}
-
- svo.reg_start = pci_resource_start(svo.pci_dev,1);
+
+ svo.reg_start = pci_resource_start(svo.pci_dev, 1);
svo.reg_size = pci_resource_len(svo.pci_dev, 1);
if (!svo.reg_start) {
printk(KERN_ERR "svo: svo has no device base address\n");
pci_set_master(svo.pci_dev);
+ /* register number is set to force
+ * because of the camera device (/dev/video0)
+ */
if (video_register_device(svo.video_dev0, VFL_TYPE_GRABBER,
- video_nr) < 0) {
+ 1) < 0) { /* set to /dev/video1 */
printk(KERN_ERR "svo: video_register_device failed\n");
goto outreqirq;
}
if (video_register_device(svo.video_dev1, VFL_TYPE_GRABBER,
- video_nr) < 0) {
+ 2) < 0) { /* set to /dev/video2 */
printk(KERN_ERR "svo: video_register_device failed\n");
goto outreqirq;
}
.name = "svo",
.id_table = svo_pci_tbl,
.probe = svo_initdev,
-// .remove = __devexit_p(cx8800_finidev),
+/* .remove = __devexit_p(cx8800_finidev), */
#ifdef CONFIG_PM
-// .suspend = cx8800_suspend,
-// .resume = cx8800_resume,
+/* .suspend = cx8800_suspend, */
+/* .resume = cx8800_resume, */
#endif
};
static int __init svo_init(void)
{
- printk(KERN_INFO "svo: Tizen virtual overlay driver version %d.%d loaded\n",
+ printk(KERN_INFO "svo: Maru overlay driver version %d.%d loaded\n",
SVO_DRIVER_MAJORVERSION, SVO_DRIVER_MINORVERSION);
return pci_register_driver(&svo_pci_driver);
}
module_init(svo_init);
-module_exit(svo_fini);
+module_exit(svo_fini);