Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v3.3-rc3 880 lines 22 kB view raw
1/* 2 * Colour AR M64278(VGA) driver for Video4Linux 3 * 4 * Copyright (C) 2003 Takeo Takahashi <takahashi.takeo@renesas.com> 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License 8 * as published by the Free Software Foundation; either version 9 * 2 of the License, or (at your option) any later version. 10 * 11 * Some code is taken from AR driver sample program for M3T-M32700UT. 12 * 13 * AR driver sample (M32R SDK): 14 * Copyright (c) 2003 RENESAS TECHNOROGY CORPORATION 15 * AND RENESAS SOLUTIONS CORPORATION 16 * All Rights Reserved. 17 * 18 * 2003-09-01: Support w3cam by Takeo Takahashi 19 */ 20 21#include <linux/init.h> 22#include <linux/module.h> 23#include <linux/delay.h> 24#include <linux/errno.h> 25#include <linux/fs.h> 26#include <linux/kernel.h> 27#include <linux/slab.h> 28#include <linux/mm.h> 29#include <linux/sched.h> 30#include <linux/videodev2.h> 31#include <media/v4l2-common.h> 32#include <media/v4l2-device.h> 33#include <media/v4l2-ioctl.h> 34#include <linux/mutex.h> 35 36#include <asm/uaccess.h> 37#include <asm/m32r.h> 38#include <asm/io.h> 39#include <asm/dma.h> 40#include <asm/byteorder.h> 41 42#if 0 43#define DEBUG(n, args...) printk(KERN_INFO args) 44#define CHECK_LOST 1 45#else 46#define DEBUG(n, args...) 47#define CHECK_LOST 0 48#endif 49 50/* 51 * USE_INT is always 0, interrupt mode is not available 52 * on linux due to lack of speed 53 */ 54#define USE_INT 0 /* Don't modify */ 55 56#define VERSION "0.0.5" 57 58#define ar_inl(addr) inl((unsigned long)(addr)) 59#define ar_outl(val, addr) outl((unsigned long)(val), (unsigned long)(addr)) 60 61extern struct cpuinfo_m32r boot_cpu_data; 62 63/* 64 * CCD pixel size 65 * Note that M32700UT does not support CIF mode, but QVGA is 66 * supported by M32700UT hardware using VGA mode of AR LSI. 67 * 68 * Supported: VGA (Normal mode, Interlace mode) 69 * QVGA (Always Interlace mode of VGA) 70 * 71 */ 72#define AR_WIDTH_VGA 640 73#define AR_HEIGHT_VGA 480 74#define AR_WIDTH_QVGA 320 75#define AR_HEIGHT_QVGA 240 76#define MIN_AR_WIDTH AR_WIDTH_QVGA 77#define MIN_AR_HEIGHT AR_HEIGHT_QVGA 78#define MAX_AR_WIDTH AR_WIDTH_VGA 79#define MAX_AR_HEIGHT AR_HEIGHT_VGA 80 81/* bits & bytes per pixel */ 82#define AR_BITS_PER_PIXEL 16 83#define AR_BYTES_PER_PIXEL (AR_BITS_PER_PIXEL / 8) 84 85/* line buffer size */ 86#define AR_LINE_BYTES_VGA (AR_WIDTH_VGA * AR_BYTES_PER_PIXEL) 87#define AR_LINE_BYTES_QVGA (AR_WIDTH_QVGA * AR_BYTES_PER_PIXEL) 88#define MAX_AR_LINE_BYTES AR_LINE_BYTES_VGA 89 90/* frame size & type */ 91#define AR_FRAME_BYTES_VGA \ 92 (AR_WIDTH_VGA * AR_HEIGHT_VGA * AR_BYTES_PER_PIXEL) 93#define AR_FRAME_BYTES_QVGA \ 94 (AR_WIDTH_QVGA * AR_HEIGHT_QVGA * AR_BYTES_PER_PIXEL) 95#define MAX_AR_FRAME_BYTES \ 96 (MAX_AR_WIDTH * MAX_AR_HEIGHT * AR_BYTES_PER_PIXEL) 97 98#define AR_MAX_FRAME 15 99 100/* capture size */ 101#define AR_SIZE_VGA 0 102#define AR_SIZE_QVGA 1 103 104/* capture mode */ 105#define AR_MODE_INTERLACE 0 106#define AR_MODE_NORMAL 1 107 108struct ar { 109 struct v4l2_device v4l2_dev; 110 struct video_device vdev; 111 unsigned int start_capture; /* duaring capture in INT. mode. */ 112#if USE_INT 113 unsigned char *line_buff; /* DMA line buffer */ 114#endif 115 unsigned char *frame[MAX_AR_HEIGHT]; /* frame data */ 116 short size; /* capture size */ 117 short mode; /* capture mode */ 118 int width, height; 119 int frame_bytes, line_bytes; 120 wait_queue_head_t wait; 121 struct mutex lock; 122}; 123 124static struct ar ardev; 125 126static int video_nr = -1; /* video device number (first free) */ 127static unsigned char yuv[MAX_AR_FRAME_BYTES]; 128 129/* module parameters */ 130/* default frequency */ 131#define DEFAULT_FREQ 50 /* 50 or 75 (MHz) is available as BCLK */ 132static int freq = DEFAULT_FREQ; /* BCLK: available 50 or 70 (MHz) */ 133static int vga; /* default mode(0:QVGA mode, other:VGA mode) */ 134static int vga_interlace; /* 0 is normal mode for, else interlace mode */ 135module_param(freq, int, 0); 136module_param(vga, int, 0); 137module_param(vga_interlace, int, 0); 138 139static void wait_for_vsync(void) 140{ 141 while (ar_inl(ARVCR0) & ARVCR0_VDS) /* wait for VSYNC */ 142 cpu_relax(); 143 while (!(ar_inl(ARVCR0) & ARVCR0_VDS)) /* wait for VSYNC */ 144 cpu_relax(); 145} 146 147static void wait_acknowledge(void) 148{ 149 int i; 150 151 for (i = 0; i < 1000; i++) 152 cpu_relax(); 153 while (ar_inl(PLDI2CSTS) & PLDI2CSTS_NOACK) 154 cpu_relax(); 155} 156 157/******************************************************************* 158 * I2C functions 159 *******************************************************************/ 160static void iic(int n, unsigned long addr, unsigned long data1, unsigned long data2, 161 unsigned long data3) 162{ 163 int i; 164 165 /* Slave Address */ 166 ar_outl(addr, PLDI2CDATA); 167 wait_for_vsync(); 168 169 /* Start */ 170 ar_outl(1, PLDI2CCND); 171 wait_acknowledge(); 172 173 /* Transfer data 1 */ 174 ar_outl(data1, PLDI2CDATA); 175 wait_for_vsync(); 176 ar_outl(PLDI2CSTEN_STEN, PLDI2CSTEN); 177 wait_acknowledge(); 178 179 /* Transfer data 2 */ 180 ar_outl(data2, PLDI2CDATA); 181 wait_for_vsync(); 182 ar_outl(PLDI2CSTEN_STEN, PLDI2CSTEN); 183 wait_acknowledge(); 184 185 if (n == 3) { 186 /* Transfer data 3 */ 187 ar_outl(data3, PLDI2CDATA); 188 wait_for_vsync(); 189 ar_outl(PLDI2CSTEN_STEN, PLDI2CSTEN); 190 wait_acknowledge(); 191 } 192 193 /* Stop */ 194 for (i = 0; i < 100; i++) 195 cpu_relax(); 196 ar_outl(2, PLDI2CCND); 197 ar_outl(2, PLDI2CCND); 198 199 while (ar_inl(PLDI2CSTS) & PLDI2CSTS_BB) 200 cpu_relax(); 201} 202 203 204static void init_iic(void) 205{ 206 DEBUG(1, "init_iic:\n"); 207 208 /* 209 * ICU Setting (iic) 210 */ 211 /* I2C Setting */ 212 ar_outl(0x0, PLDI2CCR); /* I2CCR Disable */ 213 ar_outl(0x0300, PLDI2CMOD); /* I2CMOD ACK/8b-data/7b-addr/auto */ 214 ar_outl(0x1, PLDI2CACK); /* I2CACK ACK */ 215 216 /* I2C CLK */ 217 /* 50MH-100k */ 218 if (freq == 75) 219 ar_outl(369, PLDI2CFREQ); /* BCLK = 75MHz */ 220 else if (freq == 50) 221 ar_outl(244, PLDI2CFREQ); /* BCLK = 50MHz */ 222 else 223 ar_outl(244, PLDI2CFREQ); /* default: BCLK = 50MHz */ 224 ar_outl(0x1, PLDI2CCR); /* I2CCR Enable */ 225} 226 227/************************************************************************** 228 * 229 * Video4Linux Interface functions 230 * 231 **************************************************************************/ 232 233static inline void disable_dma(void) 234{ 235 ar_outl(0x8000, M32R_DMAEN_PORTL); /* disable DMA0 */ 236} 237 238static inline void enable_dma(void) 239{ 240 ar_outl(0x8080, M32R_DMAEN_PORTL); /* enable DMA0 */ 241} 242 243static inline void clear_dma_status(void) 244{ 245 ar_outl(0x8000, M32R_DMAEDET_PORTL); /* clear status */ 246} 247 248static void wait_for_vertical_sync(struct ar *ar, int exp_line) 249{ 250#if CHECK_LOST 251 int tmout = 10000; /* FIXME */ 252 int l; 253 254 /* 255 * check HCOUNT because we cannot check vertical sync. 256 */ 257 for (; tmout >= 0; tmout--) { 258 l = ar_inl(ARVHCOUNT); 259 if (l == exp_line) 260 break; 261 } 262 if (tmout < 0) 263 v4l2_err(&ar->v4l2_dev, "lost %d -> %d\n", exp_line, l); 264#else 265 while (ar_inl(ARVHCOUNT) != exp_line) 266 cpu_relax(); 267#endif 268} 269 270static ssize_t ar_read(struct file *file, char *buf, size_t count, loff_t *ppos) 271{ 272 struct ar *ar = video_drvdata(file); 273 long ret = ar->frame_bytes; /* return read bytes */ 274 unsigned long arvcr1 = 0; 275 unsigned long flags; 276 unsigned char *p; 277 int h, w; 278 unsigned char *py, *pu, *pv; 279#if !USE_INT 280 int l; 281#endif 282 283 DEBUG(1, "ar_read()\n"); 284 285 if (ar->size == AR_SIZE_QVGA) 286 arvcr1 |= ARVCR1_QVGA; 287 if (ar->mode == AR_MODE_NORMAL) 288 arvcr1 |= ARVCR1_NORMAL; 289 290 mutex_lock(&ar->lock); 291 292#if USE_INT 293 local_irq_save(flags); 294 disable_dma(); 295 ar_outl(0xa1871300, M32R_DMA0CR0_PORTL); 296 ar_outl(0x01000000, M32R_DMA0CR1_PORTL); 297 298 /* set AR FIFO address as source(BSEL5) */ 299 ar_outl(ARDATA32, M32R_DMA0CSA_PORTL); 300 ar_outl(ARDATA32, M32R_DMA0RSA_PORTL); 301 ar_outl(ar->line_buff, M32R_DMA0CDA_PORTL); /* destination addr. */ 302 ar_outl(ar->line_buff, M32R_DMA0RDA_PORTL); /* reload address */ 303 ar_outl(ar->line_bytes, M32R_DMA0CBCUT_PORTL); /* byte count (bytes) */ 304 ar_outl(ar->line_bytes, M32R_DMA0RBCUT_PORTL); /* reload count (bytes) */ 305 306 /* 307 * Okay, kick AR LSI to invoke an interrupt 308 */ 309 ar->start_capture = 0; 310 ar_outl(arvcr1 | ARVCR1_HIEN, ARVCR1); 311 local_irq_restore(flags); 312 /* .... AR interrupts .... */ 313 interruptible_sleep_on(&ar->wait); 314 if (signal_pending(current)) { 315 printk(KERN_ERR "arv: interrupted while get frame data.\n"); 316 ret = -EINTR; 317 goto out_up; 318 } 319#else /* ! USE_INT */ 320 /* polling */ 321 ar_outl(arvcr1, ARVCR1); 322 disable_dma(); 323 ar_outl(0x8000, M32R_DMAEDET_PORTL); 324 ar_outl(0xa0861300, M32R_DMA0CR0_PORTL); 325 ar_outl(0x01000000, M32R_DMA0CR1_PORTL); 326 ar_outl(ARDATA32, M32R_DMA0CSA_PORTL); 327 ar_outl(ARDATA32, M32R_DMA0RSA_PORTL); 328 ar_outl(ar->line_bytes, M32R_DMA0CBCUT_PORTL); 329 ar_outl(ar->line_bytes, M32R_DMA0RBCUT_PORTL); 330 331 local_irq_save(flags); 332 while (ar_inl(ARVHCOUNT) != 0) /* wait for 0 */ 333 cpu_relax(); 334 if (ar->mode == AR_MODE_INTERLACE && ar->size == AR_SIZE_VGA) { 335 for (h = 0; h < ar->height; h++) { 336 wait_for_vertical_sync(ar, h); 337 if (h < (AR_HEIGHT_VGA/2)) 338 l = h << 1; 339 else 340 l = (((h - (AR_HEIGHT_VGA/2)) << 1) + 1); 341 ar_outl(virt_to_phys(ar->frame[l]), M32R_DMA0CDA_PORTL); 342 enable_dma(); 343 while (!(ar_inl(M32R_DMAEDET_PORTL) & 0x8000)) 344 cpu_relax(); 345 disable_dma(); 346 clear_dma_status(); 347 ar_outl(0xa0861300, M32R_DMA0CR0_PORTL); 348 } 349 } else { 350 for (h = 0; h < ar->height; h++) { 351 wait_for_vertical_sync(ar, h); 352 ar_outl(virt_to_phys(ar->frame[h]), M32R_DMA0CDA_PORTL); 353 enable_dma(); 354 while (!(ar_inl(M32R_DMAEDET_PORTL) & 0x8000)) 355 cpu_relax(); 356 disable_dma(); 357 clear_dma_status(); 358 ar_outl(0xa0861300, M32R_DMA0CR0_PORTL); 359 } 360 } 361 local_irq_restore(flags); 362#endif /* ! USE_INT */ 363 364 /* 365 * convert YUV422 to YUV422P 366 * +--------------------+ 367 * | Y0,Y1,... | 368 * | ..............Yn | 369 * +--------------------+ 370 * | U0,U1,........Un | 371 * +--------------------+ 372 * | V0,V1,........Vn | 373 * +--------------------+ 374 */ 375 py = yuv; 376 pu = py + (ar->frame_bytes / 2); 377 pv = pu + (ar->frame_bytes / 4); 378 for (h = 0; h < ar->height; h++) { 379 p = ar->frame[h]; 380 for (w = 0; w < ar->line_bytes; w += 4) { 381 *py++ = *p++; 382 *pu++ = *p++; 383 *py++ = *p++; 384 *pv++ = *p++; 385 } 386 } 387 if (copy_to_user(buf, yuv, ar->frame_bytes)) { 388 v4l2_err(&ar->v4l2_dev, "failed while copy_to_user yuv.\n"); 389 ret = -EFAULT; 390 goto out_up; 391 } 392 DEBUG(1, "ret = %d\n", ret); 393out_up: 394 mutex_unlock(&ar->lock); 395 return ret; 396} 397 398static int ar_querycap(struct file *file, void *priv, 399 struct v4l2_capability *vcap) 400{ 401 struct ar *ar = video_drvdata(file); 402 403 strlcpy(vcap->driver, ar->vdev.name, sizeof(vcap->driver)); 404 strlcpy(vcap->card, "Colour AR VGA", sizeof(vcap->card)); 405 strlcpy(vcap->bus_info, "Platform", sizeof(vcap->bus_info)); 406 vcap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE; 407 return 0; 408} 409 410static int ar_enum_input(struct file *file, void *fh, struct v4l2_input *vin) 411{ 412 if (vin->index > 0) 413 return -EINVAL; 414 strlcpy(vin->name, "Camera", sizeof(vin->name)); 415 vin->type = V4L2_INPUT_TYPE_CAMERA; 416 vin->audioset = 0; 417 vin->tuner = 0; 418 vin->std = V4L2_STD_ALL; 419 vin->status = 0; 420 return 0; 421} 422 423static int ar_g_input(struct file *file, void *fh, unsigned int *inp) 424{ 425 *inp = 0; 426 return 0; 427} 428 429static int ar_s_input(struct file *file, void *fh, unsigned int inp) 430{ 431 return inp ? -EINVAL : 0; 432} 433 434static int ar_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt) 435{ 436 struct ar *ar = video_drvdata(file); 437 struct v4l2_pix_format *pix = &fmt->fmt.pix; 438 439 pix->width = ar->width; 440 pix->height = ar->height; 441 pix->pixelformat = V4L2_PIX_FMT_YUV422P; 442 pix->field = (ar->mode == AR_MODE_NORMAL) ? V4L2_FIELD_NONE : V4L2_FIELD_INTERLACED; 443 pix->bytesperline = ar->width; 444 pix->sizeimage = 2 * ar->width * ar->height; 445 /* Just a guess */ 446 pix->colorspace = V4L2_COLORSPACE_SMPTE170M; 447 return 0; 448} 449 450static int ar_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt) 451{ 452 struct ar *ar = video_drvdata(file); 453 struct v4l2_pix_format *pix = &fmt->fmt.pix; 454 455 if (pix->height <= AR_HEIGHT_QVGA || pix->width <= AR_WIDTH_QVGA) { 456 pix->height = AR_HEIGHT_QVGA; 457 pix->width = AR_WIDTH_QVGA; 458 pix->field = V4L2_FIELD_INTERLACED; 459 } else { 460 pix->height = AR_HEIGHT_VGA; 461 pix->width = AR_WIDTH_VGA; 462 pix->field = vga_interlace ? V4L2_FIELD_INTERLACED : V4L2_FIELD_NONE; 463 } 464 pix->pixelformat = V4L2_PIX_FMT_YUV422P; 465 pix->bytesperline = ar->width; 466 pix->sizeimage = 2 * ar->width * ar->height; 467 /* Just a guess */ 468 pix->colorspace = V4L2_COLORSPACE_SMPTE170M; 469 return 0; 470} 471 472static int ar_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt) 473{ 474 struct ar *ar = video_drvdata(file); 475 struct v4l2_pix_format *pix = &fmt->fmt.pix; 476 int ret = ar_try_fmt_vid_cap(file, fh, fmt); 477 478 if (ret) 479 return ret; 480 mutex_lock(&ar->lock); 481 ar->width = pix->width; 482 ar->height = pix->height; 483 if (ar->width == AR_WIDTH_VGA) { 484 ar->size = AR_SIZE_VGA; 485 ar->frame_bytes = AR_FRAME_BYTES_VGA; 486 ar->line_bytes = AR_LINE_BYTES_VGA; 487 if (vga_interlace) 488 ar->mode = AR_MODE_INTERLACE; 489 else 490 ar->mode = AR_MODE_NORMAL; 491 } else { 492 ar->size = AR_SIZE_QVGA; 493 ar->frame_bytes = AR_FRAME_BYTES_QVGA; 494 ar->line_bytes = AR_LINE_BYTES_QVGA; 495 ar->mode = AR_MODE_INTERLACE; 496 } 497 /* Ok we figured out what to use from our wide choice */ 498 mutex_unlock(&ar->lock); 499 return 0; 500} 501 502static int ar_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc *fmt) 503{ 504 static struct v4l2_fmtdesc formats[] = { 505 { 0, 0, 0, 506 "YUV 4:2:2 Planar", V4L2_PIX_FMT_YUV422P, 507 { 0, 0, 0, 0 } 508 }, 509 }; 510 enum v4l2_buf_type type = fmt->type; 511 512 if (fmt->index > 0) 513 return -EINVAL; 514 515 *fmt = formats[fmt->index]; 516 fmt->type = type; 517 return 0; 518} 519 520#if USE_INT 521/* 522 * Interrupt handler 523 */ 524static void ar_interrupt(int irq, void *dev) 525{ 526 struct ar *ar = dev; 527 unsigned int line_count; 528 unsigned int line_number; 529 unsigned int arvcr1; 530 531 line_count = ar_inl(ARVHCOUNT); /* line number */ 532 if (ar->mode == AR_MODE_INTERLACE && ar->size == AR_SIZE_VGA) { 533 /* operations for interlace mode */ 534 if (line_count < (AR_HEIGHT_VGA / 2)) /* even line */ 535 line_number = (line_count << 1); 536 else /* odd line */ 537 line_number = 538 (((line_count - (AR_HEIGHT_VGA / 2)) << 1) + 1); 539 } else { 540 line_number = line_count; 541 } 542 543 if (line_number == 0) { 544 /* 545 * It is an interrupt for line 0. 546 * we have to start capture. 547 */ 548 disable_dma(); 549#if 0 550 ar_outl(ar->line_buff, M32R_DMA0CDA_PORTL); /* needless? */ 551#endif 552 memcpy(ar->frame[0], ar->line_buff, ar->line_bytes); 553#if 0 554 ar_outl(0xa1861300, M32R_DMA0CR0_PORTL); 555#endif 556 enable_dma(); 557 ar->start_capture = 1; /* during capture */ 558 return; 559 } 560 561 if (ar->start_capture == 1 && line_number <= (ar->height - 1)) { 562 disable_dma(); 563 memcpy(ar->frame[line_number], ar->line_buff, ar->line_bytes); 564 565 /* 566 * if captured all line of a frame, disable AR interrupt 567 * and wake a process up. 568 */ 569 if (line_number == (ar->height - 1)) { /* end of line */ 570 571 ar->start_capture = 0; 572 573 /* disable AR interrupt request */ 574 arvcr1 = ar_inl(ARVCR1); 575 arvcr1 &= ~ARVCR1_HIEN; /* clear int. flag */ 576 ar_outl(arvcr1, ARVCR1); /* disable */ 577 wake_up_interruptible(&ar->wait); 578 } else { 579#if 0 580 ar_outl(ar->line_buff, M32R_DMA0CDA_PORTL); 581 ar_outl(0xa1861300, M32R_DMA0CR0_PORTL); 582#endif 583 enable_dma(); 584 } 585 } 586} 587#endif 588 589/* 590 * ar_initialize() 591 * ar_initialize() is called by video_register_device() and 592 * initializes AR LSI and peripherals. 593 * 594 * -1 is returned in all failures. 595 * 0 is returned in success. 596 * 597 */ 598static int ar_initialize(struct ar *ar) 599{ 600 unsigned long cr = 0; 601 int i, found = 0; 602 603 DEBUG(1, "ar_initialize:\n"); 604 605 /* 606 * initialize AR LSI 607 */ 608 ar_outl(0, ARVCR0); /* assert reset of AR LSI */ 609 for (i = 0; i < 0x18; i++) /* wait for over 10 cycles @ 27MHz */ 610 cpu_relax(); 611 ar_outl(ARVCR0_RST, ARVCR0); /* negate reset of AR LSI (enable) */ 612 for (i = 0; i < 0x40d; i++) /* wait for over 420 cycles @ 27MHz */ 613 cpu_relax(); 614 615 /* AR uses INT3 of CPU as interrupt pin. */ 616 ar_outl(ARINTSEL_INT3, ARINTSEL); 617 618 if (ar->size == AR_SIZE_QVGA) 619 cr |= ARVCR1_QVGA; 620 if (ar->mode == AR_MODE_NORMAL) 621 cr |= ARVCR1_NORMAL; 622 ar_outl(cr, ARVCR1); 623 624 /* 625 * Initialize IIC so that CPU can communicate with AR LSI, 626 * and send boot commands to AR LSI. 627 */ 628 init_iic(); 629 630 for (i = 0; i < 0x100000; i++) { /* > 0xa1d10, 56ms */ 631 if ((ar_inl(ARVCR0) & ARVCR0_VDS)) { /* VSYNC */ 632 found = 1; 633 break; 634 } 635 } 636 637 if (found == 0) 638 return -ENODEV; 639 640 v4l2_info(&ar->v4l2_dev, "Initializing "); 641 642 iic(2, 0x78, 0x11, 0x01, 0x00); /* start */ 643 iic(3, 0x78, 0x12, 0x00, 0x06); 644 iic(3, 0x78, 0x12, 0x12, 0x30); 645 iic(3, 0x78, 0x12, 0x15, 0x58); 646 iic(3, 0x78, 0x12, 0x17, 0x30); 647 printk(KERN_CONT "."); 648 iic(3, 0x78, 0x12, 0x1a, 0x97); 649 iic(3, 0x78, 0x12, 0x1b, 0xff); 650 iic(3, 0x78, 0x12, 0x1c, 0xff); 651 iic(3, 0x78, 0x12, 0x26, 0x10); 652 iic(3, 0x78, 0x12, 0x27, 0x00); 653 printk(KERN_CONT "."); 654 iic(2, 0x78, 0x34, 0x02, 0x00); 655 iic(2, 0x78, 0x7a, 0x10, 0x00); 656 iic(2, 0x78, 0x80, 0x39, 0x00); 657 iic(2, 0x78, 0x81, 0xe6, 0x00); 658 iic(2, 0x78, 0x8d, 0x00, 0x00); 659 printk(KERN_CONT "."); 660 iic(2, 0x78, 0x8e, 0x0c, 0x00); 661 iic(2, 0x78, 0x8f, 0x00, 0x00); 662#if 0 663 iic(2, 0x78, 0x90, 0x00, 0x00); /* AWB on=1 off=0 */ 664#endif 665 iic(2, 0x78, 0x93, 0x01, 0x00); 666 iic(2, 0x78, 0x94, 0xcd, 0x00); 667 iic(2, 0x78, 0x95, 0x00, 0x00); 668 printk(KERN_CONT "."); 669 iic(2, 0x78, 0x96, 0xa0, 0x00); 670 iic(2, 0x78, 0x97, 0x00, 0x00); 671 iic(2, 0x78, 0x98, 0x60, 0x00); 672 iic(2, 0x78, 0x99, 0x01, 0x00); 673 iic(2, 0x78, 0x9a, 0x19, 0x00); 674 printk(KERN_CONT "."); 675 iic(2, 0x78, 0x9b, 0x02, 0x00); 676 iic(2, 0x78, 0x9c, 0xe8, 0x00); 677 iic(2, 0x78, 0x9d, 0x02, 0x00); 678 iic(2, 0x78, 0x9e, 0x2e, 0x00); 679 iic(2, 0x78, 0xb8, 0x78, 0x00); 680 iic(2, 0x78, 0xba, 0x05, 0x00); 681#if 0 682 iic(2, 0x78, 0x83, 0x8c, 0x00); /* brightness */ 683#endif 684 printk(KERN_CONT "."); 685 686 /* color correction */ 687 iic(3, 0x78, 0x49, 0x00, 0x95); /* a */ 688 iic(3, 0x78, 0x49, 0x01, 0x96); /* b */ 689 iic(3, 0x78, 0x49, 0x03, 0x85); /* c */ 690 iic(3, 0x78, 0x49, 0x04, 0x97); /* d */ 691 iic(3, 0x78, 0x49, 0x02, 0x7e); /* e(Lo) */ 692 iic(3, 0x78, 0x49, 0x05, 0xa4); /* f(Lo) */ 693 iic(3, 0x78, 0x49, 0x06, 0x04); /* e(Hi) */ 694 iic(3, 0x78, 0x49, 0x07, 0x04); /* e(Hi) */ 695 iic(2, 0x78, 0x48, 0x01, 0x00); /* on=1 off=0 */ 696 697 printk(KERN_CONT "."); 698 iic(2, 0x78, 0x11, 0x00, 0x00); /* end */ 699 printk(KERN_CONT " done\n"); 700 return 0; 701} 702 703 704/**************************************************************************** 705 * 706 * Video4Linux Module functions 707 * 708 ****************************************************************************/ 709 710static const struct v4l2_file_operations ar_fops = { 711 .owner = THIS_MODULE, 712 .read = ar_read, 713 .unlocked_ioctl = video_ioctl2, 714}; 715 716static const struct v4l2_ioctl_ops ar_ioctl_ops = { 717 .vidioc_querycap = ar_querycap, 718 .vidioc_g_input = ar_g_input, 719 .vidioc_s_input = ar_s_input, 720 .vidioc_enum_input = ar_enum_input, 721 .vidioc_enum_fmt_vid_cap = ar_enum_fmt_vid_cap, 722 .vidioc_g_fmt_vid_cap = ar_g_fmt_vid_cap, 723 .vidioc_s_fmt_vid_cap = ar_s_fmt_vid_cap, 724 .vidioc_try_fmt_vid_cap = ar_try_fmt_vid_cap, 725}; 726 727#define ALIGN4(x) ((((int)(x)) & 0x3) == 0) 728 729static int __init ar_init(void) 730{ 731 struct ar *ar; 732 struct v4l2_device *v4l2_dev; 733 int ret; 734 int i; 735 736 ar = &ardev; 737 v4l2_dev = &ar->v4l2_dev; 738 strlcpy(v4l2_dev->name, "arv", sizeof(v4l2_dev->name)); 739 v4l2_info(v4l2_dev, "Colour AR VGA driver %s\n", VERSION); 740 741 ret = v4l2_device_register(NULL, v4l2_dev); 742 if (ret < 0) { 743 v4l2_err(v4l2_dev, "Could not register v4l2_device\n"); 744 return ret; 745 } 746 ret = -EIO; 747 748#if USE_INT 749 /* allocate a DMA buffer for 1 line. */ 750 ar->line_buff = kmalloc(MAX_AR_LINE_BYTES, GFP_KERNEL | GFP_DMA); 751 if (ar->line_buff == NULL || !ALIGN4(ar->line_buff)) { 752 v4l2_err(v4l2_dev, "buffer allocation failed for DMA.\n"); 753 ret = -ENOMEM; 754 goto out_end; 755 } 756#endif 757 /* allocate buffers for a frame */ 758 for (i = 0; i < MAX_AR_HEIGHT; i++) { 759 ar->frame[i] = kmalloc(MAX_AR_LINE_BYTES, GFP_KERNEL); 760 if (ar->frame[i] == NULL || !ALIGN4(ar->frame[i])) { 761 v4l2_err(v4l2_dev, "buffer allocation failed for frame.\n"); 762 ret = -ENOMEM; 763 goto out_line_buff; 764 } 765 } 766 767 strlcpy(ar->vdev.name, "Colour AR VGA", sizeof(ar->vdev.name)); 768 ar->vdev.v4l2_dev = v4l2_dev; 769 ar->vdev.fops = &ar_fops; 770 ar->vdev.ioctl_ops = &ar_ioctl_ops; 771 ar->vdev.release = video_device_release_empty; 772 video_set_drvdata(&ar->vdev, ar); 773 774 if (vga) { 775 ar->width = AR_WIDTH_VGA; 776 ar->height = AR_HEIGHT_VGA; 777 ar->size = AR_SIZE_VGA; 778 ar->frame_bytes = AR_FRAME_BYTES_VGA; 779 ar->line_bytes = AR_LINE_BYTES_VGA; 780 if (vga_interlace) 781 ar->mode = AR_MODE_INTERLACE; 782 else 783 ar->mode = AR_MODE_NORMAL; 784 } else { 785 ar->width = AR_WIDTH_QVGA; 786 ar->height = AR_HEIGHT_QVGA; 787 ar->size = AR_SIZE_QVGA; 788 ar->frame_bytes = AR_FRAME_BYTES_QVGA; 789 ar->line_bytes = AR_LINE_BYTES_QVGA; 790 ar->mode = AR_MODE_INTERLACE; 791 } 792 mutex_init(&ar->lock); 793 init_waitqueue_head(&ar->wait); 794 795#if USE_INT 796 if (request_irq(M32R_IRQ_INT3, ar_interrupt, 0, "arv", ar)) { 797 v4l2_err("request_irq(%d) failed.\n", M32R_IRQ_INT3); 798 ret = -EIO; 799 goto out_irq; 800 } 801#endif 802 803 if (ar_initialize(ar) != 0) { 804 v4l2_err(v4l2_dev, "M64278 not found.\n"); 805 ret = -ENODEV; 806 goto out_dev; 807 } 808 809 /* 810 * ok, we can initialize h/w according to parameters, 811 * so register video device as a frame grabber type. 812 * device is named "video[0-64]". 813 * video_register_device() initializes h/w using ar_initialize(). 814 */ 815 if (video_register_device(&ar->vdev, VFL_TYPE_GRABBER, video_nr) != 0) { 816 /* return -1, -ENFILE(full) or others */ 817 v4l2_err(v4l2_dev, "register video (Colour AR) failed.\n"); 818 ret = -ENODEV; 819 goto out_dev; 820 } 821 822 v4l2_info(v4l2_dev, "%s: Found M64278 VGA (IRQ %d, Freq %dMHz).\n", 823 video_device_node_name(&ar->vdev), M32R_IRQ_INT3, freq); 824 825 return 0; 826 827out_dev: 828#if USE_INT 829 free_irq(M32R_IRQ_INT3, ar); 830 831out_irq: 832#endif 833 for (i = 0; i < MAX_AR_HEIGHT; i++) 834 kfree(ar->frame[i]); 835 836out_line_buff: 837#if USE_INT 838 kfree(ar->line_buff); 839 840out_end: 841#endif 842 v4l2_device_unregister(&ar->v4l2_dev); 843 return ret; 844} 845 846 847static int __init ar_init_module(void) 848{ 849 freq = (boot_cpu_data.bus_clock / 1000000); 850 printk(KERN_INFO "arv: Bus clock %d\n", freq); 851 if (freq != 50 && freq != 75) 852 freq = DEFAULT_FREQ; 853 return ar_init(); 854} 855 856static void __exit ar_cleanup_module(void) 857{ 858 struct ar *ar; 859 int i; 860 861 ar = &ardev; 862 video_unregister_device(&ar->vdev); 863#if USE_INT 864 free_irq(M32R_IRQ_INT3, ar); 865#endif 866 for (i = 0; i < MAX_AR_HEIGHT; i++) 867 kfree(ar->frame[i]); 868#if USE_INT 869 kfree(ar->line_buff); 870#endif 871 v4l2_device_unregister(&ar->v4l2_dev); 872} 873 874module_init(ar_init_module); 875module_exit(ar_cleanup_module); 876 877MODULE_AUTHOR("Takeo Takahashi <takahashi.takeo@renesas.com>"); 878MODULE_DESCRIPTION("Colour AR M64278(VGA) for Video4Linux"); 879MODULE_LICENSE("GPL"); 880MODULE_VERSION(VERSION);