Commit b8e56b6f authored by Hans Verkuil's avatar Hans Verkuil Committed by Mauro Carvalho Chehab

V4L/DVB: arv: convert to V4L2

Converted this old V4L1 driver to V4L2.
I would like to thank Takeo Takahashi who very kindly tested this
driver for me. Much appreciated!
Signed-off-by: default avatarHans Verkuil <hverkuil@xs4all.nl>
Tested-by: default avatarTakeo Takahashi <takahashi.takeo@renesas.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent debff5a7
...@@ -807,7 +807,7 @@ source "drivers/media/video/saa7164/Kconfig" ...@@ -807,7 +807,7 @@ source "drivers/media/video/saa7164/Kconfig"
config VIDEO_M32R_AR config VIDEO_M32R_AR
tristate "AR devices" tristate "AR devices"
depends on M32R && VIDEO_V4L1 depends on M32R && VIDEO_V4L2
---help--- ---help---
This is a video4linux driver for the Renesas AR (Artificial Retina) This is a video4linux driver for the Renesas AR (Artificial Retina)
camera module. camera module.
......
...@@ -27,8 +27,10 @@ ...@@ -27,8 +27,10 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/videodev.h> #include <linux/version.h>
#include <linux/videodev2.h>
#include <media/v4l2-common.h> #include <media/v4l2-common.h>
#include <media/v4l2-device.h>
#include <media/v4l2-ioctl.h> #include <media/v4l2-ioctl.h>
#include <linux/mutex.h> #include <linux/mutex.h>
...@@ -52,7 +54,7 @@ ...@@ -52,7 +54,7 @@
*/ */
#define USE_INT 0 /* Don't modify */ #define USE_INT 0 /* Don't modify */
#define VERSION "0.03" #define VERSION "0.04"
#define ar_inl(addr) inl((unsigned long)(addr)) #define ar_inl(addr) inl((unsigned long)(addr))
#define ar_outl(val, addr) outl((unsigned long)(val), (unsigned long)(addr)) #define ar_outl(val, addr) outl((unsigned long)(val), (unsigned long)(addr))
...@@ -79,7 +81,7 @@ extern struct cpuinfo_m32r boot_cpu_data; ...@@ -79,7 +81,7 @@ extern struct cpuinfo_m32r boot_cpu_data;
/* bits & bytes per pixel */ /* bits & bytes per pixel */
#define AR_BITS_PER_PIXEL 16 #define AR_BITS_PER_PIXEL 16
#define AR_BYTES_PER_PIXEL (AR_BITS_PER_PIXEL/8) #define AR_BYTES_PER_PIXEL (AR_BITS_PER_PIXEL / 8)
/* line buffer size */ /* line buffer size */
#define AR_LINE_BYTES_VGA (AR_WIDTH_VGA * AR_BYTES_PER_PIXEL) #define AR_LINE_BYTES_VGA (AR_WIDTH_VGA * AR_BYTES_PER_PIXEL)
...@@ -104,8 +106,9 @@ extern struct cpuinfo_m32r boot_cpu_data; ...@@ -104,8 +106,9 @@ extern struct cpuinfo_m32r boot_cpu_data;
#define AR_MODE_INTERLACE 0 #define AR_MODE_INTERLACE 0
#define AR_MODE_NORMAL 1 #define AR_MODE_NORMAL 1
struct ar_device { struct ar {
struct video_device *vdev; struct v4l2_device v4l2_dev;
struct video_device vdev;
unsigned int start_capture; /* duaring capture in INT. mode. */ unsigned int start_capture; /* duaring capture in INT. mode. */
#if USE_INT #if USE_INT
unsigned char *line_buff; /* DMA line buffer */ unsigned char *line_buff; /* DMA line buffer */
...@@ -116,12 +119,13 @@ struct ar_device { ...@@ -116,12 +119,13 @@ struct ar_device {
int width, height; int width, height;
int frame_bytes, line_bytes; int frame_bytes, line_bytes;
wait_queue_head_t wait; wait_queue_head_t wait;
unsigned long in_use;
struct mutex lock; struct mutex lock;
}; };
static struct ar ardev;
static int video_nr = -1; /* video device number (first free) */ static int video_nr = -1; /* video device number (first free) */
static unsigned char yuv[MAX_AR_FRAME_BYTES]; static unsigned char yuv[MAX_AR_FRAME_BYTES];
/* module parameters */ /* module parameters */
/* default frequency */ /* default frequency */
...@@ -133,9 +137,7 @@ module_param(freq, int, 0); ...@@ -133,9 +137,7 @@ module_param(freq, int, 0);
module_param(vga, int, 0); module_param(vga, int, 0);
module_param(vga_interlace, int, 0); module_param(vga_interlace, int, 0);
static int ar_initialize(struct video_device *dev); static void wait_for_vsync(void)
static inline void wait_for_vsync(void)
{ {
while (ar_inl(ARVCR0) & ARVCR0_VDS) /* wait for VSYNC */ while (ar_inl(ARVCR0) & ARVCR0_VDS) /* wait for VSYNC */
cpu_relax(); cpu_relax();
...@@ -143,7 +145,7 @@ static inline void wait_for_vsync(void) ...@@ -143,7 +145,7 @@ static inline void wait_for_vsync(void)
cpu_relax(); cpu_relax();
} }
static inline void wait_acknowledge(void) static void wait_acknowledge(void)
{ {
int i; int i;
...@@ -156,7 +158,7 @@ static inline void wait_acknowledge(void) ...@@ -156,7 +158,7 @@ static inline void wait_acknowledge(void)
/******************************************************************* /*******************************************************************
* I2C functions * I2C functions
*******************************************************************/ *******************************************************************/
void iic(int n, unsigned long addr, unsigned long data1, unsigned long data2, static void iic(int n, unsigned long addr, unsigned long data1, unsigned long data2,
unsigned long data3) unsigned long data3)
{ {
int i; int i;
...@@ -200,7 +202,7 @@ void iic(int n, unsigned long addr, unsigned long data1, unsigned long data2, ...@@ -200,7 +202,7 @@ void iic(int n, unsigned long addr, unsigned long data1, unsigned long data2,
} }
void init_iic(void) static void init_iic(void)
{ {
DEBUG(1, "init_iic:\n"); DEBUG(1, "init_iic:\n");
...@@ -244,7 +246,7 @@ static inline void clear_dma_status(void) ...@@ -244,7 +246,7 @@ static inline void clear_dma_status(void)
ar_outl(0x8000, M32R_DMAEDET_PORTL); /* clear status */ ar_outl(0x8000, M32R_DMAEDET_PORTL); /* clear status */
} }
static inline void wait_for_vertical_sync(int exp_line) static void wait_for_vertical_sync(struct ar *ar, int exp_line)
{ {
#if CHECK_LOST #if CHECK_LOST
int tmout = 10000; /* FIXME */ int tmout = 10000; /* FIXME */
...@@ -259,7 +261,7 @@ static inline void wait_for_vertical_sync(int exp_line) ...@@ -259,7 +261,7 @@ static inline void wait_for_vertical_sync(int exp_line)
break; break;
} }
if (tmout < 0) if (tmout < 0)
printk(KERN_ERR "arv: lost %d -> %d\n", exp_line, l); v4l2_err(&ar->v4l2_dev, "lost %d -> %d\n", exp_line, l);
#else #else
while (ar_inl(ARVHCOUNT) != exp_line) while (ar_inl(ARVHCOUNT) != exp_line)
cpu_relax(); cpu_relax();
...@@ -268,8 +270,7 @@ static inline void wait_for_vertical_sync(int exp_line) ...@@ -268,8 +270,7 @@ static inline void wait_for_vertical_sync(int exp_line)
static ssize_t ar_read(struct file *file, char *buf, size_t count, loff_t *ppos) static ssize_t ar_read(struct file *file, char *buf, size_t count, loff_t *ppos)
{ {
struct video_device *v = video_devdata(file); struct ar *ar = video_drvdata(file);
struct ar_device *ar = video_get_drvdata(v);
long ret = ar->frame_bytes; /* return read bytes */ long ret = ar->frame_bytes; /* return read bytes */
unsigned long arvcr1 = 0; unsigned long arvcr1 = 0;
unsigned long flags; unsigned long flags;
...@@ -304,7 +305,7 @@ static ssize_t ar_read(struct file *file, char *buf, size_t count, loff_t *ppos) ...@@ -304,7 +305,7 @@ static ssize_t ar_read(struct file *file, char *buf, size_t count, loff_t *ppos)
ar_outl(ar->line_bytes, M32R_DMA0RBCUT_PORTL); /* reload count (bytes) */ ar_outl(ar->line_bytes, M32R_DMA0RBCUT_PORTL); /* reload count (bytes) */
/* /*
* Okey , kicks AR LSI to invoke an interrupt * Okay, kick AR LSI to invoke an interrupt
*/ */
ar->start_capture = 0; ar->start_capture = 0;
ar_outl(arvcr1 | ARVCR1_HIEN, ARVCR1); ar_outl(arvcr1 | ARVCR1_HIEN, ARVCR1);
...@@ -333,7 +334,7 @@ static ssize_t ar_read(struct file *file, char *buf, size_t count, loff_t *ppos) ...@@ -333,7 +334,7 @@ static ssize_t ar_read(struct file *file, char *buf, size_t count, loff_t *ppos)
cpu_relax(); cpu_relax();
if (ar->mode == AR_MODE_INTERLACE && ar->size == AR_SIZE_VGA) { if (ar->mode == AR_MODE_INTERLACE && ar->size == AR_SIZE_VGA) {
for (h = 0; h < ar->height; h++) { for (h = 0; h < ar->height; h++) {
wait_for_vertical_sync(h); wait_for_vertical_sync(ar, h);
if (h < (AR_HEIGHT_VGA/2)) if (h < (AR_HEIGHT_VGA/2))
l = h << 1; l = h << 1;
else else
...@@ -348,7 +349,7 @@ static ssize_t ar_read(struct file *file, char *buf, size_t count, loff_t *ppos) ...@@ -348,7 +349,7 @@ static ssize_t ar_read(struct file *file, char *buf, size_t count, loff_t *ppos)
} }
} else { } else {
for (h = 0; h < ar->height; h++) { for (h = 0; h < ar->height; h++) {
wait_for_vertical_sync(h); wait_for_vertical_sync(ar, h);
ar_outl(virt_to_phys(ar->frame[h]), M32R_DMA0CDA_PORTL); ar_outl(virt_to_phys(ar->frame[h]), M32R_DMA0CDA_PORTL);
enable_dma(); enable_dma();
while (!(ar_inl(M32R_DMAEDET_PORTL) & 0x8000)) while (!(ar_inl(M32R_DMAEDET_PORTL) & 0x8000))
...@@ -385,7 +386,7 @@ static ssize_t ar_read(struct file *file, char *buf, size_t count, loff_t *ppos) ...@@ -385,7 +386,7 @@ static ssize_t ar_read(struct file *file, char *buf, size_t count, loff_t *ppos)
} }
} }
if (copy_to_user(buf, yuv, ar->frame_bytes)) { if (copy_to_user(buf, yuv, ar->frame_bytes)) {
printk(KERN_ERR "arv: failed while copy_to_user yuv.\n"); v4l2_err(&ar->v4l2_dev, "failed while copy_to_user yuv.\n");
ret = -EFAULT; ret = -EFAULT;
goto out_up; goto out_up;
} }
...@@ -395,153 +396,127 @@ static ssize_t ar_read(struct file *file, char *buf, size_t count, loff_t *ppos) ...@@ -395,153 +396,127 @@ static ssize_t ar_read(struct file *file, char *buf, size_t count, loff_t *ppos)
return ret; return ret;
} }
static long ar_do_ioctl(struct file *file, unsigned int cmd, void *arg) static int ar_querycap(struct file *file, void *priv,
struct v4l2_capability *vcap)
{ {
struct video_device *dev = video_devdata(file); struct ar *ar = video_drvdata(file);
struct ar_device *ar = video_get_drvdata(dev);
strlcpy(vcap->driver, ar->vdev.name, sizeof(vcap->driver));
DEBUG(1, "ar_ioctl()\n"); strlcpy(vcap->card, "Colour AR VGA", sizeof(vcap->card));
switch (cmd) { strlcpy(vcap->bus_info, "Platform", sizeof(vcap->bus_info));
case VIDIOCGCAP: vcap->version = KERNEL_VERSION(0, 0, 4);
{ vcap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE;
struct video_capability *b = arg; return 0;
DEBUG(1, "VIDIOCGCAP:\n"); }
strcpy(b->name, ar->vdev->name);
b->type = VID_TYPE_CAPTURE; static int ar_enum_input(struct file *file, void *fh, struct v4l2_input *vin)
b->channels = 0; {
b->audios = 0; if (vin->index > 0)
b->maxwidth = MAX_AR_WIDTH;
b->maxheight = MAX_AR_HEIGHT;
b->minwidth = MIN_AR_WIDTH;
b->minheight = MIN_AR_HEIGHT;
return 0;
}
case VIDIOCGCHAN:
DEBUG(1, "VIDIOCGCHAN:\n");
return 0;
case VIDIOCSCHAN:
DEBUG(1, "VIDIOCSCHAN:\n");
return 0;
case VIDIOCGTUNER:
DEBUG(1, "VIDIOCGTUNER:\n");
return 0;
case VIDIOCSTUNER:
DEBUG(1, "VIDIOCSTUNER:\n");
return 0;
case VIDIOCGPICT:
DEBUG(1, "VIDIOCGPICT:\n");
return 0;
case VIDIOCSPICT:
DEBUG(1, "VIDIOCSPICT:\n");
return 0;
case VIDIOCCAPTURE:
DEBUG(1, "VIDIOCCAPTURE:\n");
return -EINVAL; return -EINVAL;
case VIDIOCGWIN: strlcpy(vin->name, "Camera", sizeof(vin->name));
{ vin->type = V4L2_INPUT_TYPE_CAMERA;
struct video_window *w = arg; vin->audioset = 0;
DEBUG(1, "VIDIOCGWIN:\n"); vin->tuner = 0;
memset(w, 0, sizeof(*w)); vin->std = V4L2_STD_ALL;
w->width = ar->width; vin->status = 0;
w->height = ar->height; return 0;
return 0; }
static int ar_g_input(struct file *file, void *fh, unsigned int *inp)
{
*inp = 0;
return 0;
}
static int ar_s_input(struct file *file, void *fh, unsigned int inp)
{
return inp ? -EINVAL : 0;
}
static int ar_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
{
struct ar *ar = video_drvdata(file);
struct v4l2_pix_format *pix = &fmt->fmt.pix;
pix->width = ar->width;
pix->height = ar->height;
pix->pixelformat = V4L2_PIX_FMT_YUV422P;
pix->field = (ar->mode == AR_MODE_NORMAL) ? V4L2_FIELD_NONE : V4L2_FIELD_INTERLACED;
pix->bytesperline = ar->width;
pix->sizeimage = 2 * ar->width * ar->height;
/* Just a guess */
pix->colorspace = V4L2_COLORSPACE_SMPTE170M;
return 0;
}
static int ar_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
{
struct ar *ar = video_drvdata(file);
struct v4l2_pix_format *pix = &fmt->fmt.pix;
if (pix->height <= AR_HEIGHT_QVGA || pix->width <= AR_WIDTH_QVGA) {
pix->height = AR_HEIGHT_QVGA;
pix->width = AR_WIDTH_QVGA;
pix->field = V4L2_FIELD_INTERLACED;
} else {
pix->height = AR_HEIGHT_VGA;
pix->width = AR_WIDTH_VGA;
pix->field = vga_interlace ? V4L2_FIELD_INTERLACED : V4L2_FIELD_NONE;
} }
case VIDIOCSWIN: pix->pixelformat = V4L2_PIX_FMT_YUV422P;
{ pix->bytesperline = ar->width;
struct video_window *w = arg; pix->sizeimage = 2 * ar->width * ar->height;
DEBUG(1, "VIDIOCSWIN:\n"); /* Just a guess */
if ((w->width != AR_WIDTH_VGA || w->height != AR_HEIGHT_VGA) && pix->colorspace = V4L2_COLORSPACE_SMPTE170M;
(w->width != AR_WIDTH_QVGA || w->height != AR_HEIGHT_QVGA)) return 0;
return -EINVAL; }
mutex_lock(&ar->lock); static int ar_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
ar->width = w->width; {
ar->height = w->height; struct ar *ar = video_drvdata(file);
if (ar->width == AR_WIDTH_VGA) { struct v4l2_pix_format *pix = &fmt->fmt.pix;
ar->size = AR_SIZE_VGA; int ret = ar_try_fmt_vid_cap(file, fh, fmt);
ar->frame_bytes = AR_FRAME_BYTES_VGA;
ar->line_bytes = AR_LINE_BYTES_VGA; if (ret)
if (vga_interlace) return ret;
ar->mode = AR_MODE_INTERLACE; mutex_lock(&ar->lock);
else ar->width = pix->width;
ar->mode = AR_MODE_NORMAL; ar->height = pix->height;
} else { if (ar->width == AR_WIDTH_VGA) {
ar->size = AR_SIZE_QVGA; ar->size = AR_SIZE_VGA;
ar->frame_bytes = AR_FRAME_BYTES_QVGA; ar->frame_bytes = AR_FRAME_BYTES_VGA;
ar->line_bytes = AR_LINE_BYTES_QVGA; ar->line_bytes = AR_LINE_BYTES_VGA;
if (vga_interlace)
ar->mode = AR_MODE_INTERLACE; ar->mode = AR_MODE_INTERLACE;
} else
mutex_unlock(&ar->lock); ar->mode = AR_MODE_NORMAL;
return 0; } else {
} ar->size = AR_SIZE_QVGA;
case VIDIOCGFBUF: ar->frame_bytes = AR_FRAME_BYTES_QVGA;
DEBUG(1, "VIDIOCGFBUF:\n"); ar->line_bytes = AR_LINE_BYTES_QVGA;
return -EINVAL; ar->mode = AR_MODE_INTERLACE;
case VIDIOCSFBUF:
DEBUG(1, "VIDIOCSFBUF:\n");
return -EINVAL;
case VIDIOCKEY:
DEBUG(1, "VIDIOCKEY:\n");
return 0;
case VIDIOCGFREQ:
DEBUG(1, "VIDIOCGFREQ:\n");
return -EINVAL;
case VIDIOCSFREQ:
DEBUG(1, "VIDIOCSFREQ:\n");
return -EINVAL;
case VIDIOCGAUDIO:
DEBUG(1, "VIDIOCGAUDIO:\n");
return -EINVAL;
case VIDIOCSAUDIO:
DEBUG(1, "VIDIOCSAUDIO:\n");
return -EINVAL;
case VIDIOCSYNC:
DEBUG(1, "VIDIOCSYNC:\n");
return -EINVAL;
case VIDIOCMCAPTURE:
DEBUG(1, "VIDIOCMCAPTURE:\n");
return -EINVAL;
case VIDIOCGMBUF:
DEBUG(1, "VIDIOCGMBUF:\n");
return -EINVAL;
case VIDIOCGUNIT:
DEBUG(1, "VIDIOCGUNIT:\n");
return -EINVAL;
case VIDIOCGCAPTURE:
DEBUG(1, "VIDIOCGCAPTURE:\n");
return -EINVAL;
case VIDIOCSCAPTURE:
DEBUG(1, "VIDIOCSCAPTURE:\n");
return -EINVAL;
case VIDIOCSPLAYMODE:
DEBUG(1, "VIDIOCSPLAYMODE:\n");
return -EINVAL;
case VIDIOCSWRITEMODE:
DEBUG(1, "VIDIOCSWRITEMODE:\n");
return -EINVAL;
case VIDIOCGPLAYINFO:
DEBUG(1, "VIDIOCGPLAYINFO:\n");
return -EINVAL;
case VIDIOCSMICROCODE:
DEBUG(1, "VIDIOCSMICROCODE:\n");
return -EINVAL;
case VIDIOCGVBIFMT:
DEBUG(1, "VIDIOCGVBIFMT:\n");
return -EINVAL;
case VIDIOCSVBIFMT:
DEBUG(1, "VIDIOCSVBIFMT:\n");
return -EINVAL;
default:
DEBUG(1, "Unknown ioctl(0x%08x)\n", cmd);
return -ENOIOCTLCMD;
} }
/* Ok we figured out what to use from our wide choice */
mutex_unlock(&ar->lock);
return 0; return 0;
} }
static long ar_ioctl(struct file *file, unsigned int cmd, static int ar_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc *fmt)
unsigned long arg)
{ {
return video_usercopy(file, cmd, arg, ar_do_ioctl); static struct v4l2_fmtdesc formats[] = {
{ 0, 0, 0,
"YUV 4:2:2 Planar", V4L2_PIX_FMT_YUV422P,
{ 0, 0, 0, 0 }
},
};
enum v4l2_buf_type type = fmt->type;
if (fmt->index > 0)
return -EINVAL;
*fmt = formats[fmt->index];
fmt->type = type;
return 0;
} }
#if USE_INT #if USE_INT
...@@ -550,7 +525,7 @@ static long ar_ioctl(struct file *file, unsigned int cmd, ...@@ -550,7 +525,7 @@ static long ar_ioctl(struct file *file, unsigned int cmd,
*/ */
static void ar_interrupt(int irq, void *dev) static void ar_interrupt(int irq, void *dev)
{ {
struct ar_device *ar = dev; struct ar *ar = dev;
unsigned int line_count; unsigned int line_count;
unsigned int line_number; unsigned int line_number;
unsigned int arvcr1; unsigned int arvcr1;
...@@ -622,9 +597,8 @@ static void ar_interrupt(int irq, void *dev) ...@@ -622,9 +597,8 @@ static void ar_interrupt(int irq, void *dev)
* 0 is returned in success. * 0 is returned in success.
* *
*/ */
static int ar_initialize(struct video_device *dev) static int ar_initialize(struct ar *ar)
{ {
struct ar_device *ar = video_get_drvdata(dev);
unsigned long cr = 0; unsigned long cr = 0;
int i, found = 0; int i, found = 0;
...@@ -665,7 +639,7 @@ static int ar_initialize(struct video_device *dev) ...@@ -665,7 +639,7 @@ static int ar_initialize(struct video_device *dev)
if (found == 0) if (found == 0)
return -ENODEV; return -ENODEV;
printk(KERN_INFO "arv: Initializing "); v4l2_info(&ar->v4l2_dev, "Initializing ");
iic(2, 0x78, 0x11, 0x01, 0x00); /* start */ iic(2, 0x78, 0x11, 0x01, 0x00); /* start */
iic(3, 0x78, 0x12, 0x00, 0x06); iic(3, 0x78, 0x12, 0x00, 0x06);
...@@ -729,65 +703,55 @@ static int ar_initialize(struct video_device *dev) ...@@ -729,65 +703,55 @@ static int ar_initialize(struct video_device *dev)
} }
void ar_release(struct video_device *vfd)
{
struct ar_device *ar = video_get_drvdata(vfd);
mutex_lock(&ar->lock);
video_device_release(vfd);
}
/**************************************************************************** /****************************************************************************
* *
* Video4Linux Module functions * Video4Linux Module functions
* *
****************************************************************************/ ****************************************************************************/
static struct ar_device ardev;
static int ar_exclusive_open(struct file *file)
{
return test_and_set_bit(0, &ardev.in_use) ? -EBUSY : 0;
}
static int ar_exclusive_release(struct file *file)
{
clear_bit(0, &ardev.in_use);
return 0;
}
static const struct v4l2_file_operations ar_fops = { static const struct v4l2_file_operations ar_fops = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.open = ar_exclusive_open,
.release = ar_exclusive_release,
.read = ar_read, .read = ar_read,
.ioctl = ar_ioctl, .ioctl = video_ioctl2,
}; };
static struct video_device ar_template = { static const struct v4l2_ioctl_ops ar_ioctl_ops = {
.name = "Colour AR VGA", .vidioc_querycap = ar_querycap,
.fops = &ar_fops, .vidioc_g_input = ar_g_input,
.release = ar_release, .vidioc_s_input = ar_s_input,
.vidioc_enum_input = ar_enum_input,
.vidioc_enum_fmt_vid_cap = ar_enum_fmt_vid_cap,
.vidioc_g_fmt_vid_cap = ar_g_fmt_vid_cap,
.vidioc_s_fmt_vid_cap = ar_s_fmt_vid_cap,
.vidioc_try_fmt_vid_cap = ar_try_fmt_vid_cap,
}; };
#define ALIGN4(x) ((((int)(x)) & 0x3) == 0) #define ALIGN4(x) ((((int)(x)) & 0x3) == 0)
static int __init ar_init(void) static int __init ar_init(void)
{ {
struct ar_device *ar; struct ar *ar;
struct v4l2_device *v4l2_dev;
int ret; int ret;
int i; int i;
DEBUG(1, "ar_init:\n");
ret = -EIO;
printk(KERN_INFO "arv: Colour AR VGA driver %s\n", VERSION);
ar = &ardev; ar = &ardev;
memset(ar, 0, sizeof(struct ar_device)); v4l2_dev = &ar->v4l2_dev;
strlcpy(v4l2_dev->name, "arv", sizeof(v4l2_dev->name));
v4l2_info(v4l2_dev, "Colour AR VGA driver %s\n", VERSION);
ret = v4l2_device_register(NULL, v4l2_dev);
if (ret < 0) {
v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
return ret;
}
ret = -EIO;
#if USE_INT #if USE_INT
/* allocate a DMA buffer for 1 line. */ /* allocate a DMA buffer for 1 line. */
ar->line_buff = kmalloc(MAX_AR_LINE_BYTES, GFP_KERNEL | GFP_DMA); ar->line_buff = kmalloc(MAX_AR_LINE_BYTES, GFP_KERNEL | GFP_DMA);
if (ar->line_buff == NULL || !ALIGN4(ar->line_buff)) { if (ar->line_buff == NULL || !ALIGN4(ar->line_buff)) {
printk(KERN_ERR "arv: buffer allocation failed for DMA.\n"); v4l2_err(v4l2_dev, "buffer allocation failed for DMA.\n");
ret = -ENOMEM; ret = -ENOMEM;
goto out_end; goto out_end;
} }
...@@ -796,19 +760,18 @@ static int __init ar_init(void) ...@@ -796,19 +760,18 @@ static int __init ar_init(void)
for (i = 0; i < MAX_AR_HEIGHT; i++) { for (i = 0; i < MAX_AR_HEIGHT; i++) {
ar->frame[i] = kmalloc(MAX_AR_LINE_BYTES, GFP_KERNEL); ar->frame[i] = kmalloc(MAX_AR_LINE_BYTES, GFP_KERNEL);
if (ar->frame[i] == NULL || !ALIGN4(ar->frame[i])) { if (ar->frame[i] == NULL || !ALIGN4(ar->frame[i])) {
printk(KERN_ERR "arv: buffer allocation failed for frame.\n"); v4l2_err(v4l2_dev, "buffer allocation failed for frame.\n");
ret = -ENOMEM; ret = -ENOMEM;
goto out_line_buff; goto out_line_buff;
} }
} }
ar->vdev = video_device_alloc(); strlcpy(ar->vdev.name, "Colour AR VGA", sizeof(ar->vdev.name));
if (!ar->vdev) { ar->vdev.v4l2_dev = v4l2_dev;
printk(KERN_ERR "arv: video_device_alloc() failed\n"); ar->vdev.fops = &ar_fops;
return -ENOMEM; ar->vdev.ioctl_ops = &ar_ioctl_ops;
} ar->vdev.release = video_device_release_empty;
memcpy(ar->vdev, &ar_template, sizeof(ar_template)); video_set_drvdata(&ar->vdev, ar);
video_set_drvdata(ar->vdev, ar);
if (vga) { if (vga) {
ar->width = AR_WIDTH_VGA; ar->width = AR_WIDTH_VGA;
...@@ -833,14 +796,14 @@ static int __init ar_init(void) ...@@ -833,14 +796,14 @@ static int __init ar_init(void)
#if USE_INT #if USE_INT
if (request_irq(M32R_IRQ_INT3, ar_interrupt, 0, "arv", ar)) { if (request_irq(M32R_IRQ_INT3, ar_interrupt, 0, "arv", ar)) {
printk(KERN_ERR "arv: request_irq(%d) failed.\n", M32R_IRQ_INT3); v4l2_err("request_irq(%d) failed.\n", M32R_IRQ_INT3);
ret = -EIO; ret = -EIO;
goto out_irq; goto out_irq;
} }
#endif #endif
if (ar_initialize(ar->vdev) != 0) { if (ar_initialize(ar) != 0) {
printk(KERN_ERR "arv: M64278 not found.\n"); v4l2_err(v4l2_dev, "M64278 not found.\n");
ret = -ENODEV; ret = -ENODEV;
goto out_dev; goto out_dev;
} }
...@@ -851,15 +814,15 @@ static int __init ar_init(void) ...@@ -851,15 +814,15 @@ static int __init ar_init(void)
* device is named "video[0-64]". * device is named "video[0-64]".
* video_register_device() initializes h/w using ar_initialize(). * video_register_device() initializes h/w using ar_initialize().
*/ */
if (video_register_device(ar->vdev, VFL_TYPE_GRABBER, video_nr) != 0) { if (video_register_device(&ar->vdev, VFL_TYPE_GRABBER, video_nr) != 0) {
/* return -1, -ENFILE(full) or others */ /* return -1, -ENFILE(full) or others */
printk(KERN_ERR "arv: register video (Colour AR) failed.\n"); v4l2_err(v4l2_dev, "register video (Colour AR) failed.\n");
ret = -ENODEV; ret = -ENODEV;
goto out_dev; goto out_dev;
} }
printk(KERN_INFO "%s: Found M64278 VGA (IRQ %d, Freq %dMHz).\n", v4l2_info(v4l2_dev, "%s: Found M64278 VGA (IRQ %d, Freq %dMHz).\n",
video_device_node_name(ar->vdev), M32R_IRQ_INT3, freq); video_device_node_name(&ar->vdev), M32R_IRQ_INT3, freq);
return 0; return 0;
...@@ -878,6 +841,7 @@ static int __init ar_init(void) ...@@ -878,6 +841,7 @@ static int __init ar_init(void)
out_end: out_end:
#endif #endif
v4l2_device_unregister(&ar->v4l2_dev);
return ret; return ret;
} }
...@@ -893,11 +857,11 @@ static int __init ar_init_module(void) ...@@ -893,11 +857,11 @@ static int __init ar_init_module(void)
static void __exit ar_cleanup_module(void) static void __exit ar_cleanup_module(void)
{ {
struct ar_device *ar; struct ar *ar;
int i; int i;
ar = &ardev; ar = &ardev;
video_unregister_device(ar->vdev); video_unregister_device(&ar->vdev);
#if USE_INT #if USE_INT
free_irq(M32R_IRQ_INT3, ar); free_irq(M32R_IRQ_INT3, ar);
#endif #endif
...@@ -906,6 +870,7 @@ static void __exit ar_cleanup_module(void) ...@@ -906,6 +870,7 @@ static void __exit ar_cleanup_module(void)
#if USE_INT #if USE_INT
kfree(ar->line_buff); kfree(ar->line_buff);
#endif #endif
v4l2_device_unregister(&ar->v4l2_dev);
} }
module_init(ar_init_module); module_init(ar_init_module);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment