aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/arv.c
diff options
context:
space:
mode:
authorHans Verkuil <hverkuil@xs4all.nl>2010-03-29 15:05:33 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2010-05-17 23:52:42 -0400
commitb8e56b6f6e5b6c55d4d375cc9ebd79151b44db58 (patch)
treef0b96cf0e90ae6910ec9fef4471bfb96292b40e1 /drivers/media/video/arv.c
parentdebff5a79595356b1d10063c5f5a7bcdf1b54bec (diff)
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: Hans Verkuil <hverkuil@xs4all.nl> Tested-by: Takeo Takahashi <takahashi.takeo@renesas.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/arv.c')
-rw-r--r--drivers/media/video/arv.c391
1 files changed, 178 insertions, 213 deletions
diff --git a/drivers/media/video/arv.c b/drivers/media/video/arv.c
index 9f88096a520c..31e7a123d19a 100644
--- a/drivers/media/video/arv.c
+++ b/drivers/media/video/arv.c
@@ -27,8 +27,10 @@
27#include <linux/slab.h> 27#include <linux/slab.h>
28#include <linux/mm.h> 28#include <linux/mm.h>
29#include <linux/sched.h> 29#include <linux/sched.h>
30#include <linux/videodev.h> 30#include <linux/version.h>
31#include <linux/videodev2.h>
31#include <media/v4l2-common.h> 32#include <media/v4l2-common.h>
33#include <media/v4l2-device.h>
32#include <media/v4l2-ioctl.h> 34#include <media/v4l2-ioctl.h>
33#include <linux/mutex.h> 35#include <linux/mutex.h>
34 36
@@ -52,7 +54,7 @@
52 */ 54 */
53#define USE_INT 0 /* Don't modify */ 55#define USE_INT 0 /* Don't modify */
54 56
55#define VERSION "0.03" 57#define VERSION "0.04"
56 58
57#define ar_inl(addr) inl((unsigned long)(addr)) 59#define ar_inl(addr) inl((unsigned long)(addr))
58#define ar_outl(val, addr) outl((unsigned long)(val), (unsigned long)(addr)) 60#define ar_outl(val, addr) outl((unsigned long)(val), (unsigned long)(addr))
@@ -79,7 +81,7 @@ extern struct cpuinfo_m32r boot_cpu_data;
79 81
80/* bits & bytes per pixel */ 82/* bits & bytes per pixel */
81#define AR_BITS_PER_PIXEL 16 83#define AR_BITS_PER_PIXEL 16
82#define AR_BYTES_PER_PIXEL (AR_BITS_PER_PIXEL/8) 84#define AR_BYTES_PER_PIXEL (AR_BITS_PER_PIXEL / 8)
83 85
84/* line buffer size */ 86/* line buffer size */
85#define AR_LINE_BYTES_VGA (AR_WIDTH_VGA * AR_BYTES_PER_PIXEL) 87#define AR_LINE_BYTES_VGA (AR_WIDTH_VGA * AR_BYTES_PER_PIXEL)
@@ -104,8 +106,9 @@ extern struct cpuinfo_m32r boot_cpu_data;
104#define AR_MODE_INTERLACE 0 106#define AR_MODE_INTERLACE 0
105#define AR_MODE_NORMAL 1 107#define AR_MODE_NORMAL 1
106 108
107struct ar_device { 109struct ar {
108 struct video_device *vdev; 110 struct v4l2_device v4l2_dev;
111 struct video_device vdev;
109 unsigned int start_capture; /* duaring capture in INT. mode. */ 112 unsigned int start_capture; /* duaring capture in INT. mode. */
110#if USE_INT 113#if USE_INT
111 unsigned char *line_buff; /* DMA line buffer */ 114 unsigned char *line_buff; /* DMA line buffer */
@@ -116,12 +119,13 @@ struct ar_device {
116 int width, height; 119 int width, height;
117 int frame_bytes, line_bytes; 120 int frame_bytes, line_bytes;
118 wait_queue_head_t wait; 121 wait_queue_head_t wait;
119 unsigned long in_use;
120 struct mutex lock; 122 struct mutex lock;
121}; 123};
122 124
125static struct ar ardev;
126
123static int video_nr = -1; /* video device number (first free) */ 127static int video_nr = -1; /* video device number (first free) */
124static unsigned char yuv[MAX_AR_FRAME_BYTES]; 128static unsigned char yuv[MAX_AR_FRAME_BYTES];
125 129
126/* module parameters */ 130/* module parameters */
127/* default frequency */ 131/* default frequency */
@@ -133,9 +137,7 @@ module_param(freq, int, 0);
133module_param(vga, int, 0); 137module_param(vga, int, 0);
134module_param(vga_interlace, int, 0); 138module_param(vga_interlace, int, 0);
135 139
136static int ar_initialize(struct video_device *dev); 140static void wait_for_vsync(void)
137
138static inline void wait_for_vsync(void)
139{ 141{
140 while (ar_inl(ARVCR0) & ARVCR0_VDS) /* wait for VSYNC */ 142 while (ar_inl(ARVCR0) & ARVCR0_VDS) /* wait for VSYNC */
141 cpu_relax(); 143 cpu_relax();
@@ -143,7 +145,7 @@ static inline void wait_for_vsync(void)
143 cpu_relax(); 145 cpu_relax();
144} 146}
145 147
146static inline void wait_acknowledge(void) 148static void wait_acknowledge(void)
147{ 149{
148 int i; 150 int i;
149 151
@@ -156,7 +158,7 @@ static inline void wait_acknowledge(void)
156/******************************************************************* 158/*******************************************************************
157 * I2C functions 159 * I2C functions
158 *******************************************************************/ 160 *******************************************************************/
159void iic(int n, unsigned long addr, unsigned long data1, unsigned long data2, 161static void iic(int n, unsigned long addr, unsigned long data1, unsigned long data2,
160 unsigned long data3) 162 unsigned long data3)
161{ 163{
162 int i; 164 int i;
@@ -200,7 +202,7 @@ void iic(int n, unsigned long addr, unsigned long data1, unsigned long data2,
200} 202}
201 203
202 204
203void init_iic(void) 205static void init_iic(void)
204{ 206{
205 DEBUG(1, "init_iic:\n"); 207 DEBUG(1, "init_iic:\n");
206 208
@@ -244,7 +246,7 @@ static inline void clear_dma_status(void)
244 ar_outl(0x8000, M32R_DMAEDET_PORTL); /* clear status */ 246 ar_outl(0x8000, M32R_DMAEDET_PORTL); /* clear status */
245} 247}
246 248
247static inline void wait_for_vertical_sync(int exp_line) 249static void wait_for_vertical_sync(struct ar *ar, int exp_line)
248{ 250{
249#if CHECK_LOST 251#if CHECK_LOST
250 int tmout = 10000; /* FIXME */ 252 int tmout = 10000; /* FIXME */
@@ -259,7 +261,7 @@ static inline void wait_for_vertical_sync(int exp_line)
259 break; 261 break;
260 } 262 }
261 if (tmout < 0) 263 if (tmout < 0)
262 printk(KERN_ERR "arv: lost %d -> %d\n", exp_line, l); 264 v4l2_err(&ar->v4l2_dev, "lost %d -> %d\n", exp_line, l);
263#else 265#else
264 while (ar_inl(ARVHCOUNT) != exp_line) 266 while (ar_inl(ARVHCOUNT) != exp_line)
265 cpu_relax(); 267 cpu_relax();
@@ -268,8 +270,7 @@ static inline void wait_for_vertical_sync(int exp_line)
268 270
269static ssize_t ar_read(struct file *file, char *buf, size_t count, loff_t *ppos) 271static ssize_t ar_read(struct file *file, char *buf, size_t count, loff_t *ppos)
270{ 272{
271 struct video_device *v = video_devdata(file); 273 struct ar *ar = video_drvdata(file);
272 struct ar_device *ar = video_get_drvdata(v);
273 long ret = ar->frame_bytes; /* return read bytes */ 274 long ret = ar->frame_bytes; /* return read bytes */
274 unsigned long arvcr1 = 0; 275 unsigned long arvcr1 = 0;
275 unsigned long flags; 276 unsigned long flags;
@@ -304,7 +305,7 @@ static ssize_t ar_read(struct file *file, char *buf, size_t count, loff_t *ppos)
304 ar_outl(ar->line_bytes, M32R_DMA0RBCUT_PORTL); /* reload count (bytes) */ 305 ar_outl(ar->line_bytes, M32R_DMA0RBCUT_PORTL); /* reload count (bytes) */
305 306
306 /* 307 /*
307 * Okey , kicks AR LSI to invoke an interrupt 308 * Okay, kick AR LSI to invoke an interrupt
308 */ 309 */
309 ar->start_capture = 0; 310 ar->start_capture = 0;
310 ar_outl(arvcr1 | ARVCR1_HIEN, ARVCR1); 311 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 cpu_relax(); 334 cpu_relax();
334 if (ar->mode == AR_MODE_INTERLACE && ar->size == AR_SIZE_VGA) { 335 if (ar->mode == AR_MODE_INTERLACE && ar->size == AR_SIZE_VGA) {
335 for (h = 0; h < ar->height; h++) { 336 for (h = 0; h < ar->height; h++) {
336 wait_for_vertical_sync(h); 337 wait_for_vertical_sync(ar, h);
337 if (h < (AR_HEIGHT_VGA/2)) 338 if (h < (AR_HEIGHT_VGA/2))
338 l = h << 1; 339 l = h << 1;
339 else 340 else
@@ -348,7 +349,7 @@ static ssize_t ar_read(struct file *file, char *buf, size_t count, loff_t *ppos)
348 } 349 }
349 } else { 350 } else {
350 for (h = 0; h < ar->height; h++) { 351 for (h = 0; h < ar->height; h++) {
351 wait_for_vertical_sync(h); 352 wait_for_vertical_sync(ar, h);
352 ar_outl(virt_to_phys(ar->frame[h]), M32R_DMA0CDA_PORTL); 353 ar_outl(virt_to_phys(ar->frame[h]), M32R_DMA0CDA_PORTL);
353 enable_dma(); 354 enable_dma();
354 while (!(ar_inl(M32R_DMAEDET_PORTL) & 0x8000)) 355 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 } 386 }
386 } 387 }
387 if (copy_to_user(buf, yuv, ar->frame_bytes)) { 388 if (copy_to_user(buf, yuv, ar->frame_bytes)) {
388 printk(KERN_ERR "arv: failed while copy_to_user yuv.\n"); 389 v4l2_err(&ar->v4l2_dev, "failed while copy_to_user yuv.\n");
389 ret = -EFAULT; 390 ret = -EFAULT;
390 goto out_up; 391 goto out_up;
391 } 392 }
@@ -395,153 +396,127 @@ out_up:
395 return ret; 396 return ret;
396} 397}
397 398
398static long ar_do_ioctl(struct file *file, unsigned int cmd, void *arg) 399static int ar_querycap(struct file *file, void *priv,
400 struct v4l2_capability *vcap)
399{ 401{
400 struct video_device *dev = video_devdata(file); 402 struct ar *ar = video_drvdata(file);
401 struct ar_device *ar = video_get_drvdata(dev); 403
402 404 strlcpy(vcap->driver, ar->vdev.name, sizeof(vcap->driver));
403 DEBUG(1, "ar_ioctl()\n"); 405 strlcpy(vcap->card, "Colour AR VGA", sizeof(vcap->card));
404 switch (cmd) { 406 strlcpy(vcap->bus_info, "Platform", sizeof(vcap->bus_info));
405 case VIDIOCGCAP: 407 vcap->version = KERNEL_VERSION(0, 0, 4);
406 { 408 vcap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE;
407 struct video_capability *b = arg; 409 return 0;
408 DEBUG(1, "VIDIOCGCAP:\n"); 410}
409 strcpy(b->name, ar->vdev->name); 411
410 b->type = VID_TYPE_CAPTURE; 412static int ar_enum_input(struct file *file, void *fh, struct v4l2_input *vin)
411 b->channels = 0; 413{
412 b->audios = 0; 414 if (vin->index > 0)
413 b->maxwidth = MAX_AR_WIDTH;
414 b->maxheight = MAX_AR_HEIGHT;
415 b->minwidth = MIN_AR_WIDTH;
416 b->minheight = MIN_AR_HEIGHT;
417 return 0;
418 }
419 case VIDIOCGCHAN:
420 DEBUG(1, "VIDIOCGCHAN:\n");
421 return 0;
422 case VIDIOCSCHAN:
423 DEBUG(1, "VIDIOCSCHAN:\n");
424 return 0;
425 case VIDIOCGTUNER:
426 DEBUG(1, "VIDIOCGTUNER:\n");
427 return 0;
428 case VIDIOCSTUNER:
429 DEBUG(1, "VIDIOCSTUNER:\n");
430 return 0;
431 case VIDIOCGPICT:
432 DEBUG(1, "VIDIOCGPICT:\n");
433 return 0;
434 case VIDIOCSPICT:
435 DEBUG(1, "VIDIOCSPICT:\n");
436 return 0;
437 case VIDIOCCAPTURE:
438 DEBUG(1, "VIDIOCCAPTURE:\n");
439 return -EINVAL; 415 return -EINVAL;
440 case VIDIOCGWIN: 416 strlcpy(vin->name, "Camera", sizeof(vin->name));
441 { 417 vin->type = V4L2_INPUT_TYPE_CAMERA;
442 struct video_window *w = arg; 418 vin->audioset = 0;
443 DEBUG(1, "VIDIOCGWIN:\n"); 419 vin->tuner = 0;
444 memset(w, 0, sizeof(*w)); 420 vin->std = V4L2_STD_ALL;
445 w->width = ar->width; 421 vin->status = 0;
446 w->height = ar->height; 422 return 0;
447 return 0; 423}
424
425static int ar_g_input(struct file *file, void *fh, unsigned int *inp)
426{
427 *inp = 0;
428 return 0;
429}
430
431static int ar_s_input(struct file *file, void *fh, unsigned int inp)
432{
433 return inp ? -EINVAL : 0;
434}
435
436static int ar_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
437{
438 struct ar *ar = video_drvdata(file);
439 struct v4l2_pix_format *pix = &fmt->fmt.pix;
440
441 pix->width = ar->width;
442 pix->height = ar->height;
443 pix->pixelformat = V4L2_PIX_FMT_YUV422P;
444 pix->field = (ar->mode == AR_MODE_NORMAL) ? V4L2_FIELD_NONE : V4L2_FIELD_INTERLACED;
445 pix->bytesperline = ar->width;
446 pix->sizeimage = 2 * ar->width * ar->height;
447 /* Just a guess */
448 pix->colorspace = V4L2_COLORSPACE_SMPTE170M;
449 return 0;
450}
451
452static int ar_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
453{
454 struct ar *ar = video_drvdata(file);
455 struct v4l2_pix_format *pix = &fmt->fmt.pix;
456
457 if (pix->height <= AR_HEIGHT_QVGA || pix->width <= AR_WIDTH_QVGA) {
458 pix->height = AR_HEIGHT_QVGA;
459 pix->width = AR_WIDTH_QVGA;
460 pix->field = V4L2_FIELD_INTERLACED;
461 } else {
462 pix->height = AR_HEIGHT_VGA;
463 pix->width = AR_WIDTH_VGA;
464 pix->field = vga_interlace ? V4L2_FIELD_INTERLACED : V4L2_FIELD_NONE;
448 } 465 }
449 case VIDIOCSWIN: 466 pix->pixelformat = V4L2_PIX_FMT_YUV422P;
450 { 467 pix->bytesperline = ar->width;
451 struct video_window *w = arg; 468 pix->sizeimage = 2 * ar->width * ar->height;
452 DEBUG(1, "VIDIOCSWIN:\n"); 469 /* Just a guess */
453 if ((w->width != AR_WIDTH_VGA || w->height != AR_HEIGHT_VGA) && 470 pix->colorspace = V4L2_COLORSPACE_SMPTE170M;
454 (w->width != AR_WIDTH_QVGA || w->height != AR_HEIGHT_QVGA)) 471 return 0;
455 return -EINVAL; 472}
456 473
457 mutex_lock(&ar->lock); 474static int ar_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
458 ar->width = w->width; 475{
459 ar->height = w->height; 476 struct ar *ar = video_drvdata(file);
460 if (ar->width == AR_WIDTH_VGA) { 477 struct v4l2_pix_format *pix = &fmt->fmt.pix;
461 ar->size = AR_SIZE_VGA; 478 int ret = ar_try_fmt_vid_cap(file, fh, fmt);
462 ar->frame_bytes = AR_FRAME_BYTES_VGA; 479
463 ar->line_bytes = AR_LINE_BYTES_VGA; 480 if (ret)
464 if (vga_interlace) 481 return ret;
465 ar->mode = AR_MODE_INTERLACE; 482 mutex_lock(&ar->lock);
466 else 483 ar->width = pix->width;
467 ar->mode = AR_MODE_NORMAL; 484 ar->height = pix->height;
468 } else { 485 if (ar->width == AR_WIDTH_VGA) {
469 ar->size = AR_SIZE_QVGA; 486 ar->size = AR_SIZE_VGA;
470 ar->frame_bytes = AR_FRAME_BYTES_QVGA; 487 ar->frame_bytes = AR_FRAME_BYTES_VGA;
471 ar->line_bytes = AR_LINE_BYTES_QVGA; 488 ar->line_bytes = AR_LINE_BYTES_VGA;
489 if (vga_interlace)
472 ar->mode = AR_MODE_INTERLACE; 490 ar->mode = AR_MODE_INTERLACE;
473 } 491 else
474 mutex_unlock(&ar->lock); 492 ar->mode = AR_MODE_NORMAL;
475 return 0; 493 } else {
476 } 494 ar->size = AR_SIZE_QVGA;
477 case VIDIOCGFBUF: 495 ar->frame_bytes = AR_FRAME_BYTES_QVGA;
478 DEBUG(1, "VIDIOCGFBUF:\n"); 496 ar->line_bytes = AR_LINE_BYTES_QVGA;
479 return -EINVAL; 497 ar->mode = AR_MODE_INTERLACE;
480 case VIDIOCSFBUF:
481 DEBUG(1, "VIDIOCSFBUF:\n");
482 return -EINVAL;
483 case VIDIOCKEY:
484 DEBUG(1, "VIDIOCKEY:\n");
485 return 0;
486 case VIDIOCGFREQ:
487 DEBUG(1, "VIDIOCGFREQ:\n");
488 return -EINVAL;
489 case VIDIOCSFREQ:
490 DEBUG(1, "VIDIOCSFREQ:\n");
491 return -EINVAL;
492 case VIDIOCGAUDIO:
493 DEBUG(1, "VIDIOCGAUDIO:\n");
494 return -EINVAL;
495 case VIDIOCSAUDIO:
496 DEBUG(1, "VIDIOCSAUDIO:\n");
497 return -EINVAL;
498 case VIDIOCSYNC:
499 DEBUG(1, "VIDIOCSYNC:\n");
500 return -EINVAL;
501 case VIDIOCMCAPTURE:
502 DEBUG(1, "VIDIOCMCAPTURE:\n");
503 return -EINVAL;
504 case VIDIOCGMBUF:
505 DEBUG(1, "VIDIOCGMBUF:\n");
506 return -EINVAL;
507 case VIDIOCGUNIT:
508 DEBUG(1, "VIDIOCGUNIT:\n");
509 return -EINVAL;
510 case VIDIOCGCAPTURE:
511 DEBUG(1, "VIDIOCGCAPTURE:\n");
512 return -EINVAL;
513 case VIDIOCSCAPTURE:
514 DEBUG(1, "VIDIOCSCAPTURE:\n");
515 return -EINVAL;
516 case VIDIOCSPLAYMODE:
517 DEBUG(1, "VIDIOCSPLAYMODE:\n");
518 return -EINVAL;
519 case VIDIOCSWRITEMODE:
520 DEBUG(1, "VIDIOCSWRITEMODE:\n");
521 return -EINVAL;
522 case VIDIOCGPLAYINFO:
523 DEBUG(1, "VIDIOCGPLAYINFO:\n");
524 return -EINVAL;
525 case VIDIOCSMICROCODE:
526 DEBUG(1, "VIDIOCSMICROCODE:\n");
527 return -EINVAL;
528 case VIDIOCGVBIFMT:
529 DEBUG(1, "VIDIOCGVBIFMT:\n");
530 return -EINVAL;
531 case VIDIOCSVBIFMT:
532 DEBUG(1, "VIDIOCSVBIFMT:\n");
533 return -EINVAL;
534 default:
535 DEBUG(1, "Unknown ioctl(0x%08x)\n", cmd);
536 return -ENOIOCTLCMD;
537 } 498 }
499 /* Ok we figured out what to use from our wide choice */
500 mutex_unlock(&ar->lock);
538 return 0; 501 return 0;
539} 502}
540 503
541static long ar_ioctl(struct file *file, unsigned int cmd, 504static int ar_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc *fmt)
542 unsigned long arg)
543{ 505{
544 return video_usercopy(file, cmd, arg, ar_do_ioctl); 506 static struct v4l2_fmtdesc formats[] = {
507 { 0, 0, 0,
508 "YUV 4:2:2 Planar", V4L2_PIX_FMT_YUV422P,
509 { 0, 0, 0, 0 }
510 },
511 };
512 enum v4l2_buf_type type = fmt->type;
513
514 if (fmt->index > 0)
515 return -EINVAL;
516
517 *fmt = formats[fmt->index];
518 fmt->type = type;
519 return 0;
545} 520}
546 521
547#if USE_INT 522#if USE_INT
@@ -550,7 +525,7 @@ static long ar_ioctl(struct file *file, unsigned int cmd,
550 */ 525 */
551static void ar_interrupt(int irq, void *dev) 526static void ar_interrupt(int irq, void *dev)
552{ 527{
553 struct ar_device *ar = dev; 528 struct ar *ar = dev;
554 unsigned int line_count; 529 unsigned int line_count;
555 unsigned int line_number; 530 unsigned int line_number;
556 unsigned int arvcr1; 531 unsigned int arvcr1;
@@ -622,9 +597,8 @@ static void ar_interrupt(int irq, void *dev)
622 * 0 is returned in success. 597 * 0 is returned in success.
623 * 598 *
624 */ 599 */
625static int ar_initialize(struct video_device *dev) 600static int ar_initialize(struct ar *ar)
626{ 601{
627 struct ar_device *ar = video_get_drvdata(dev);
628 unsigned long cr = 0; 602 unsigned long cr = 0;
629 int i, found = 0; 603 int i, found = 0;
630 604
@@ -665,7 +639,7 @@ static int ar_initialize(struct video_device *dev)
665 if (found == 0) 639 if (found == 0)
666 return -ENODEV; 640 return -ENODEV;
667 641
668 printk(KERN_INFO "arv: Initializing "); 642 v4l2_info(&ar->v4l2_dev, "Initializing ");
669 643
670 iic(2, 0x78, 0x11, 0x01, 0x00); /* start */ 644 iic(2, 0x78, 0x11, 0x01, 0x00); /* start */
671 iic(3, 0x78, 0x12, 0x00, 0x06); 645 iic(3, 0x78, 0x12, 0x00, 0x06);
@@ -729,65 +703,55 @@ static int ar_initialize(struct video_device *dev)
729} 703}
730 704
731 705
732void ar_release(struct video_device *vfd)
733{
734 struct ar_device *ar = video_get_drvdata(vfd);
735 mutex_lock(&ar->lock);
736 video_device_release(vfd);
737}
738
739/**************************************************************************** 706/****************************************************************************
740 * 707 *
741 * Video4Linux Module functions 708 * Video4Linux Module functions
742 * 709 *
743 ****************************************************************************/ 710 ****************************************************************************/
744static struct ar_device ardev;
745
746static int ar_exclusive_open(struct file *file)
747{
748 return test_and_set_bit(0, &ardev.in_use) ? -EBUSY : 0;
749}
750
751static int ar_exclusive_release(struct file *file)
752{
753 clear_bit(0, &ardev.in_use);
754 return 0;
755}
756 711
757static const struct v4l2_file_operations ar_fops = { 712static const struct v4l2_file_operations ar_fops = {
758 .owner = THIS_MODULE, 713 .owner = THIS_MODULE,
759 .open = ar_exclusive_open,
760 .release = ar_exclusive_release,
761 .read = ar_read, 714 .read = ar_read,
762 .ioctl = ar_ioctl, 715 .ioctl = video_ioctl2,
763}; 716};
764 717
765static struct video_device ar_template = { 718static const struct v4l2_ioctl_ops ar_ioctl_ops = {
766 .name = "Colour AR VGA", 719 .vidioc_querycap = ar_querycap,
767 .fops = &ar_fops, 720 .vidioc_g_input = ar_g_input,
768 .release = ar_release, 721 .vidioc_s_input = ar_s_input,
722 .vidioc_enum_input = ar_enum_input,
723 .vidioc_enum_fmt_vid_cap = ar_enum_fmt_vid_cap,
724 .vidioc_g_fmt_vid_cap = ar_g_fmt_vid_cap,
725 .vidioc_s_fmt_vid_cap = ar_s_fmt_vid_cap,
726 .vidioc_try_fmt_vid_cap = ar_try_fmt_vid_cap,
769}; 727};
770 728
771#define ALIGN4(x) ((((int)(x)) & 0x3) == 0) 729#define ALIGN4(x) ((((int)(x)) & 0x3) == 0)
772 730
773static int __init ar_init(void) 731static int __init ar_init(void)
774{ 732{
775 struct ar_device *ar; 733 struct ar *ar;
734 struct v4l2_device *v4l2_dev;
776 int ret; 735 int ret;
777 int i; 736 int i;
778 737
779 DEBUG(1, "ar_init:\n");
780 ret = -EIO;
781 printk(KERN_INFO "arv: Colour AR VGA driver %s\n", VERSION);
782
783 ar = &ardev; 738 ar = &ardev;
784 memset(ar, 0, sizeof(struct ar_device)); 739 v4l2_dev = &ar->v4l2_dev;
740 strlcpy(v4l2_dev->name, "arv", sizeof(v4l2_dev->name));
741 v4l2_info(v4l2_dev, "Colour AR VGA driver %s\n", VERSION);
742
743 ret = v4l2_device_register(NULL, v4l2_dev);
744 if (ret < 0) {
745 v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
746 return ret;
747 }
748 ret = -EIO;
785 749
786#if USE_INT 750#if USE_INT
787 /* allocate a DMA buffer for 1 line. */ 751 /* allocate a DMA buffer for 1 line. */
788 ar->line_buff = kmalloc(MAX_AR_LINE_BYTES, GFP_KERNEL | GFP_DMA); 752 ar->line_buff = kmalloc(MAX_AR_LINE_BYTES, GFP_KERNEL | GFP_DMA);
789 if (ar->line_buff == NULL || !ALIGN4(ar->line_buff)) { 753 if (ar->line_buff == NULL || !ALIGN4(ar->line_buff)) {
790 printk(KERN_ERR "arv: buffer allocation failed for DMA.\n"); 754 v4l2_err(v4l2_dev, "buffer allocation failed for DMA.\n");
791 ret = -ENOMEM; 755 ret = -ENOMEM;
792 goto out_end; 756 goto out_end;
793 } 757 }
@@ -796,19 +760,18 @@ static int __init ar_init(void)
796 for (i = 0; i < MAX_AR_HEIGHT; i++) { 760 for (i = 0; i < MAX_AR_HEIGHT; i++) {
797 ar->frame[i] = kmalloc(MAX_AR_LINE_BYTES, GFP_KERNEL); 761 ar->frame[i] = kmalloc(MAX_AR_LINE_BYTES, GFP_KERNEL);
798 if (ar->frame[i] == NULL || !ALIGN4(ar->frame[i])) { 762 if (ar->frame[i] == NULL || !ALIGN4(ar->frame[i])) {
799 printk(KERN_ERR "arv: buffer allocation failed for frame.\n"); 763 v4l2_err(v4l2_dev, "buffer allocation failed for frame.\n");
800 ret = -ENOMEM; 764 ret = -ENOMEM;
801 goto out_line_buff; 765 goto out_line_buff;
802 } 766 }
803 } 767 }
804 768
805 ar->vdev = video_device_alloc(); 769 strlcpy(ar->vdev.name, "Colour AR VGA", sizeof(ar->vdev.name));
806 if (!ar->vdev) { 770 ar->vdev.v4l2_dev = v4l2_dev;
807 printk(KERN_ERR "arv: video_device_alloc() failed\n"); 771 ar->vdev.fops = &ar_fops;
808 return -ENOMEM; 772 ar->vdev.ioctl_ops = &ar_ioctl_ops;
809 } 773 ar->vdev.release = video_device_release_empty;
810 memcpy(ar->vdev, &ar_template, sizeof(ar_template)); 774 video_set_drvdata(&ar->vdev, ar);
811 video_set_drvdata(ar->vdev, ar);
812 775
813 if (vga) { 776 if (vga) {
814 ar->width = AR_WIDTH_VGA; 777 ar->width = AR_WIDTH_VGA;
@@ -833,14 +796,14 @@ static int __init ar_init(void)
833 796
834#if USE_INT 797#if USE_INT
835 if (request_irq(M32R_IRQ_INT3, ar_interrupt, 0, "arv", ar)) { 798 if (request_irq(M32R_IRQ_INT3, ar_interrupt, 0, "arv", ar)) {
836 printk(KERN_ERR "arv: request_irq(%d) failed.\n", M32R_IRQ_INT3); 799 v4l2_err("request_irq(%d) failed.\n", M32R_IRQ_INT3);
837 ret = -EIO; 800 ret = -EIO;
838 goto out_irq; 801 goto out_irq;
839 } 802 }
840#endif 803#endif
841 804
842 if (ar_initialize(ar->vdev) != 0) { 805 if (ar_initialize(ar) != 0) {
843 printk(KERN_ERR "arv: M64278 not found.\n"); 806 v4l2_err(v4l2_dev, "M64278 not found.\n");
844 ret = -ENODEV; 807 ret = -ENODEV;
845 goto out_dev; 808 goto out_dev;
846 } 809 }
@@ -851,15 +814,15 @@ static int __init ar_init(void)
851 * device is named "video[0-64]". 814 * device is named "video[0-64]".
852 * video_register_device() initializes h/w using ar_initialize(). 815 * video_register_device() initializes h/w using ar_initialize().
853 */ 816 */
854 if (video_register_device(ar->vdev, VFL_TYPE_GRABBER, video_nr) != 0) { 817 if (video_register_device(&ar->vdev, VFL_TYPE_GRABBER, video_nr) != 0) {
855 /* return -1, -ENFILE(full) or others */ 818 /* return -1, -ENFILE(full) or others */
856 printk(KERN_ERR "arv: register video (Colour AR) failed.\n"); 819 v4l2_err(v4l2_dev, "register video (Colour AR) failed.\n");
857 ret = -ENODEV; 820 ret = -ENODEV;
858 goto out_dev; 821 goto out_dev;
859 } 822 }
860 823
861 printk(KERN_INFO "%s: Found M64278 VGA (IRQ %d, Freq %dMHz).\n", 824 v4l2_info(v4l2_dev, "%s: Found M64278 VGA (IRQ %d, Freq %dMHz).\n",
862 video_device_node_name(ar->vdev), M32R_IRQ_INT3, freq); 825 video_device_node_name(&ar->vdev), M32R_IRQ_INT3, freq);
863 826
864 return 0; 827 return 0;
865 828
@@ -878,6 +841,7 @@ out_line_buff:
878 841
879out_end: 842out_end:
880#endif 843#endif
844 v4l2_device_unregister(&ar->v4l2_dev);
881 return ret; 845 return ret;
882} 846}
883 847
@@ -893,11 +857,11 @@ static int __init ar_init_module(void)
893 857
894static void __exit ar_cleanup_module(void) 858static void __exit ar_cleanup_module(void)
895{ 859{
896 struct ar_device *ar; 860 struct ar *ar;
897 int i; 861 int i;
898 862
899 ar = &ardev; 863 ar = &ardev;
900 video_unregister_device(ar->vdev); 864 video_unregister_device(&ar->vdev);
901#if USE_INT 865#if USE_INT
902 free_irq(M32R_IRQ_INT3, ar); 866 free_irq(M32R_IRQ_INT3, ar);
903#endif 867#endif
@@ -906,6 +870,7 @@ static void __exit ar_cleanup_module(void)
906#if USE_INT 870#if USE_INT
907 kfree(ar->line_buff); 871 kfree(ar->line_buff);
908#endif 872#endif
873 v4l2_device_unregister(&ar->v4l2_dev);
909} 874}
910 875
911module_init(ar_init_module); 876module_init(ar_init_module);