11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Colour AR M64278(VGA) driver for Video4Linux 31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (C) 2003 Takeo Takahashi <takahashi.takeo@renesas.com> 51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This program is free software; you can redistribute it and/or 71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * modify it under the terms of the GNU General Public License 81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * as published by the Free Software Foundation; either version 91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 2 of the License, or (at your option) any later version. 101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Some code is taken from AR driver sample program for M3T-M32700UT. 121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * AR driver sample (M32R SDK): 141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (c) 2003 RENESAS TECHNOROGY CORPORATION 151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * AND RENESAS SOLUTIONS CORPORATION 161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * All Rights Reserved. 171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 2003-09-01: Support w3cam by Takeo Takahashi 191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/init.h> 221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/module.h> 231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/delay.h> 241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/errno.h> 251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/fs.h> 261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/kernel.h> 271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/slab.h> 281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/mm.h> 291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/sched.h> 30b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil#include <linux/videodev2.h> 315e87efa3b29c105f81fea785babafb098e4e046dMauro Carvalho Chehab#include <media/v4l2-common.h> 32b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil#include <media/v4l2-device.h> 33dfb9aff025c4c874f9169e2fd690ce6fee2309feAdrian Bunk#include <media/v4l2-ioctl.h> 343593cab5d62c4c7abced1076710f9bc2d8847433Ingo Molnar#include <linux/mutex.h> 351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/uaccess.h> 371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/m32r.h> 381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/io.h> 391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/dma.h> 401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/byteorder.h> 411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#if 0 4388f4423454a23375f07bb4ff3a80d209930560d0Hans Verkuil#define DEBUG(n, args...) printk(KERN_INFO args) 441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define CHECK_LOST 1 451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#else 461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define DEBUG(n, args...) 471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define CHECK_LOST 0 481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * USE_INT is always 0, interrupt mode is not available 521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * on linux due to lack of speed 531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define USE_INT 0 /* Don't modify */ 551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 561990d50b58bef127a647005fdcada6d07081d3efMauro Carvalho Chehab#define VERSION "0.0.5" 571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define ar_inl(addr) inl((unsigned long)(addr)) 5988f4423454a23375f07bb4ff3a80d209930560d0Hans Verkuil#define ar_outl(val, addr) outl((unsigned long)(val), (unsigned long)(addr)) 601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsextern struct cpuinfo_m32r boot_cpu_data; 621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * CCD pixel size 651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Note that M32700UT does not support CIF mode, but QVGA is 661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * supported by M32700UT hardware using VGA mode of AR LSI. 671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Supported: VGA (Normal mode, Interlace mode) 691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * QVGA (Always Interlace mode of VGA) 701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define AR_WIDTH_VGA 640 731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define AR_HEIGHT_VGA 480 741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define AR_WIDTH_QVGA 320 751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define AR_HEIGHT_QVGA 240 761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define MIN_AR_WIDTH AR_WIDTH_QVGA 771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define MIN_AR_HEIGHT AR_HEIGHT_QVGA 781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define MAX_AR_WIDTH AR_WIDTH_VGA 791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define MAX_AR_HEIGHT AR_HEIGHT_VGA 801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* bits & bytes per pixel */ 821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define AR_BITS_PER_PIXEL 16 83b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil#define AR_BYTES_PER_PIXEL (AR_BITS_PER_PIXEL / 8) 841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* line buffer size */ 861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define AR_LINE_BYTES_VGA (AR_WIDTH_VGA * AR_BYTES_PER_PIXEL) 871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define AR_LINE_BYTES_QVGA (AR_WIDTH_QVGA * AR_BYTES_PER_PIXEL) 881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define MAX_AR_LINE_BYTES AR_LINE_BYTES_VGA 891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* frame size & type */ 911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define AR_FRAME_BYTES_VGA \ 921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (AR_WIDTH_VGA * AR_HEIGHT_VGA * AR_BYTES_PER_PIXEL) 931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define AR_FRAME_BYTES_QVGA \ 941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (AR_WIDTH_QVGA * AR_HEIGHT_QVGA * AR_BYTES_PER_PIXEL) 951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define MAX_AR_FRAME_BYTES \ 961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (MAX_AR_WIDTH * MAX_AR_HEIGHT * AR_BYTES_PER_PIXEL) 971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define AR_MAX_FRAME 15 991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* capture size */ 1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define AR_SIZE_VGA 0 1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define AR_SIZE_QVGA 1 1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* capture mode */ 1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define AR_MODE_INTERLACE 0 1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define AR_MODE_NORMAL 1 1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 108b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuilstruct ar { 109b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil struct v4l2_device v4l2_dev; 110b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil struct video_device vdev; 1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int start_capture; /* duaring capture in INT. mode. */ 1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#if USE_INT 1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned char *line_buff; /* DMA line buffer */ 1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned char *frame[MAX_AR_HEIGHT]; /* frame data */ 1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds short size; /* capture size */ 1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds short mode; /* capture mode */ 1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int width, height; 1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int frame_bytes, line_bytes; 1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds wait_queue_head_t wait; 1213593cab5d62c4c7abced1076710f9bc2d8847433Ingo Molnar struct mutex lock; 1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 1231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 124b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuilstatic struct ar ardev; 125b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil 1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int video_nr = -1; /* video device number (first free) */ 127b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuilstatic unsigned char yuv[MAX_AR_FRAME_BYTES]; 1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* module parameters */ 1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* default frequency */ 1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define DEFAULT_FREQ 50 /* 50 or 75 (MHz) is available as BCLK */ 1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int freq = DEFAULT_FREQ; /* BCLK: available 50 or 70 (MHz) */ 133ff699e6bd02eb1c6d02c7c2b576c2ee6caab201cDouglas Schilling Landgrafstatic int vga; /* default mode(0:QVGA mode, other:VGA mode) */ 134ff699e6bd02eb1c6d02c7c2b576c2ee6caab201cDouglas Schilling Landgrafstatic int vga_interlace; /* 0 is normal mode for, else interlace mode */ 1359b565eb794eec1ccd9edcc7263ebe5b3245a1e65Eric Sesterhenn / snakebytemodule_param(freq, int, 0); 1369b565eb794eec1ccd9edcc7263ebe5b3245a1e65Eric Sesterhenn / snakebytemodule_param(vga, int, 0); 1379b565eb794eec1ccd9edcc7263ebe5b3245a1e65Eric Sesterhenn / snakebytemodule_param(vga_interlace, int, 0); 1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 139b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuilstatic void wait_for_vsync(void) 1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (ar_inl(ARVCR0) & ARVCR0_VDS) /* wait for VSYNC */ 1421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cpu_relax(); 1431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (!(ar_inl(ARVCR0) & ARVCR0_VDS)) /* wait for VSYNC */ 1441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cpu_relax(); 1451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 147b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuilstatic void wait_acknowledge(void) 1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < 1000; i++) 1521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cpu_relax(); 1531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (ar_inl(PLDI2CSTS) & PLDI2CSTS_NOACK) 1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cpu_relax(); 1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/******************************************************************* 1581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * I2C functions 1591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *******************************************************************/ 160b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuilstatic void iic(int n, unsigned long addr, unsigned long data1, unsigned long data2, 1611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long data3) 1621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 1641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 165d56410e0a594150c5ca06319da7bc8901c4d455eMauro Carvalho Chehab /* Slave Address */ 166d56410e0a594150c5ca06319da7bc8901c4d455eMauro Carvalho Chehab ar_outl(addr, PLDI2CDATA); 1671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds wait_for_vsync(); 1681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 169d56410e0a594150c5ca06319da7bc8901c4d455eMauro Carvalho Chehab /* Start */ 170d56410e0a594150c5ca06319da7bc8901c4d455eMauro Carvalho Chehab ar_outl(1, PLDI2CCND); 1711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds wait_acknowledge(); 1721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Transfer data 1 */ 174d56410e0a594150c5ca06319da7bc8901c4d455eMauro Carvalho Chehab ar_outl(data1, PLDI2CDATA); 1751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds wait_for_vsync(); 176d56410e0a594150c5ca06319da7bc8901c4d455eMauro Carvalho Chehab ar_outl(PLDI2CSTEN_STEN, PLDI2CSTEN); 1771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds wait_acknowledge(); 1781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Transfer data 2 */ 180d56410e0a594150c5ca06319da7bc8901c4d455eMauro Carvalho Chehab ar_outl(data2, PLDI2CDATA); 1811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds wait_for_vsync(); 182d56410e0a594150c5ca06319da7bc8901c4d455eMauro Carvalho Chehab ar_outl(PLDI2CSTEN_STEN, PLDI2CSTEN); 1831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds wait_acknowledge(); 1841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (n == 3) { 1861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Transfer data 3 */ 187d56410e0a594150c5ca06319da7bc8901c4d455eMauro Carvalho Chehab ar_outl(data3, PLDI2CDATA); 1881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds wait_for_vsync(); 189d56410e0a594150c5ca06319da7bc8901c4d455eMauro Carvalho Chehab ar_outl(PLDI2CSTEN_STEN, PLDI2CSTEN); 1901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds wait_acknowledge(); 191d56410e0a594150c5ca06319da7bc8901c4d455eMauro Carvalho Chehab } 1921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 193d56410e0a594150c5ca06319da7bc8901c4d455eMauro Carvalho Chehab /* Stop */ 1941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < 100; i++) 1951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cpu_relax(); 196d56410e0a594150c5ca06319da7bc8901c4d455eMauro Carvalho Chehab ar_outl(2, PLDI2CCND); 197d56410e0a594150c5ca06319da7bc8901c4d455eMauro Carvalho Chehab ar_outl(2, PLDI2CCND); 1981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (ar_inl(PLDI2CSTS) & PLDI2CSTS_BB) 2001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cpu_relax(); 2011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 204b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuilstatic void init_iic(void) 2051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DEBUG(1, "init_iic:\n"); 2071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 208d56410e0a594150c5ca06319da7bc8901c4d455eMauro Carvalho Chehab /* 2091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * ICU Setting (iic) 2101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 211d56410e0a594150c5ca06319da7bc8901c4d455eMauro Carvalho Chehab /* I2C Setting */ 212d56410e0a594150c5ca06319da7bc8901c4d455eMauro Carvalho Chehab ar_outl(0x0, PLDI2CCR); /* I2CCR Disable */ 213d56410e0a594150c5ca06319da7bc8901c4d455eMauro Carvalho Chehab ar_outl(0x0300, PLDI2CMOD); /* I2CMOD ACK/8b-data/7b-addr/auto */ 214d56410e0a594150c5ca06319da7bc8901c4d455eMauro Carvalho Chehab ar_outl(0x1, PLDI2CACK); /* I2CACK ACK */ 2151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 216657de3cd32285831a56f9f96deb85c64205c42fcTrent Piepho /* I2C CLK */ 217d56410e0a594150c5ca06319da7bc8901c4d455eMauro Carvalho Chehab /* 50MH-100k */ 21888f4423454a23375f07bb4ff3a80d209930560d0Hans Verkuil if (freq == 75) 219d56410e0a594150c5ca06319da7bc8901c4d455eMauro Carvalho Chehab ar_outl(369, PLDI2CFREQ); /* BCLK = 75MHz */ 22088f4423454a23375f07bb4ff3a80d209930560d0Hans Verkuil else if (freq == 50) 2211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ar_outl(244, PLDI2CFREQ); /* BCLK = 50MHz */ 22288f4423454a23375f07bb4ff3a80d209930560d0Hans Verkuil else 2231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ar_outl(244, PLDI2CFREQ); /* default: BCLK = 50MHz */ 224d56410e0a594150c5ca06319da7bc8901c4d455eMauro Carvalho Chehab ar_outl(0x1, PLDI2CCR); /* I2CCR Enable */ 2251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/************************************************************************** 2281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 2291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Video4Linux Interface functions 2301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 2311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds **************************************************************************/ 2321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline void disable_dma(void) 2341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ar_outl(0x8000, M32R_DMAEN_PORTL); /* disable DMA0 */ 2361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline void enable_dma(void) 2391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ar_outl(0x8080, M32R_DMAEN_PORTL); /* enable DMA0 */ 2411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline void clear_dma_status(void) 2441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ar_outl(0x8000, M32R_DMAEDET_PORTL); /* clear status */ 2461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 248b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuilstatic void wait_for_vertical_sync(struct ar *ar, int exp_line) 2491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#if CHECK_LOST 2511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int tmout = 10000; /* FIXME */ 2521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int l; 2531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 2551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * check HCOUNT because we cannot check vertical sync. 256d56410e0a594150c5ca06319da7bc8901c4d455eMauro Carvalho Chehab */ 2571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (; tmout >= 0; tmout--) { 2581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds l = ar_inl(ARVHCOUNT); 2591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (l == exp_line) 2601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 2611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (tmout < 0) 263b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil v4l2_err(&ar->v4l2_dev, "lost %d -> %d\n", exp_line, l); 2641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#else 2651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (ar_inl(ARVHCOUNT) != exp_line) 2661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cpu_relax(); 2671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 2681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic ssize_t ar_read(struct file *file, char *buf, size_t count, loff_t *ppos) 2711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 272b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil struct ar *ar = video_drvdata(file); 2731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds long ret = ar->frame_bytes; /* return read bytes */ 2741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long arvcr1 = 0; 2751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long flags; 2761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned char *p; 2771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int h, w; 2781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned char *py, *pu, *pv; 27988f4423454a23375f07bb4ff3a80d209930560d0Hans Verkuil#if !USE_INT 2801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int l; 2811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 2821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DEBUG(1, "ar_read()\n"); 2841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ar->size == AR_SIZE_QVGA) 2861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds arvcr1 |= ARVCR1_QVGA; 2871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ar->mode == AR_MODE_NORMAL) 2881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds arvcr1 |= ARVCR1_NORMAL; 2891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2903593cab5d62c4c7abced1076710f9bc2d8847433Ingo Molnar mutex_lock(&ar->lock); 2911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#if USE_INT 2931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds local_irq_save(flags); 2941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds disable_dma(); 2951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ar_outl(0xa1871300, M32R_DMA0CR0_PORTL); 2961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ar_outl(0x01000000, M32R_DMA0CR1_PORTL); 2971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* set AR FIFO address as source(BSEL5) */ 2991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ar_outl(ARDATA32, M32R_DMA0CSA_PORTL); 3001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ar_outl(ARDATA32, M32R_DMA0RSA_PORTL); 3011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ar_outl(ar->line_buff, M32R_DMA0CDA_PORTL); /* destination addr. */ 3021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ar_outl(ar->line_buff, M32R_DMA0RDA_PORTL); /* reload address */ 3031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ar_outl(ar->line_bytes, M32R_DMA0CBCUT_PORTL); /* byte count (bytes) */ 3041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ar_outl(ar->line_bytes, M32R_DMA0RBCUT_PORTL); /* reload count (bytes) */ 3051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 307b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil * Okay, kick AR LSI to invoke an interrupt 3081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 3091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ar->start_capture = 0; 3101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ar_outl(arvcr1 | ARVCR1_HIEN, ARVCR1); 3111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds local_irq_restore(flags); 3121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* .... AR interrupts .... */ 3131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds interruptible_sleep_on(&ar->wait); 3141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (signal_pending(current)) { 31588f4423454a23375f07bb4ff3a80d209930560d0Hans Verkuil printk(KERN_ERR "arv: interrupted while get frame data.\n"); 3161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret = -EINTR; 3171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out_up; 3181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#else /* ! USE_INT */ 3201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* polling */ 3211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ar_outl(arvcr1, ARVCR1); 3221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds disable_dma(); 3231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ar_outl(0x8000, M32R_DMAEDET_PORTL); 3241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ar_outl(0xa0861300, M32R_DMA0CR0_PORTL); 3251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ar_outl(0x01000000, M32R_DMA0CR1_PORTL); 3261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ar_outl(ARDATA32, M32R_DMA0CSA_PORTL); 3271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ar_outl(ARDATA32, M32R_DMA0RSA_PORTL); 3281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ar_outl(ar->line_bytes, M32R_DMA0CBCUT_PORTL); 3291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ar_outl(ar->line_bytes, M32R_DMA0RBCUT_PORTL); 3301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds local_irq_save(flags); 3321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (ar_inl(ARVHCOUNT) != 0) /* wait for 0 */ 3331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cpu_relax(); 3341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ar->mode == AR_MODE_INTERLACE && ar->size == AR_SIZE_VGA) { 3351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (h = 0; h < ar->height; h++) { 336b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil wait_for_vertical_sync(ar, h); 3371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (h < (AR_HEIGHT_VGA/2)) 3381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds l = h << 1; 3391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 3401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds l = (((h - (AR_HEIGHT_VGA/2)) << 1) + 1); 3411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ar_outl(virt_to_phys(ar->frame[l]), M32R_DMA0CDA_PORTL); 3421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds enable_dma(); 3431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (!(ar_inl(M32R_DMAEDET_PORTL) & 0x8000)) 3441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cpu_relax(); 3451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds disable_dma(); 3461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds clear_dma_status(); 3471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ar_outl(0xa0861300, M32R_DMA0CR0_PORTL); 3481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 3501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (h = 0; h < ar->height; h++) { 351b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil wait_for_vertical_sync(ar, h); 3521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ar_outl(virt_to_phys(ar->frame[h]), M32R_DMA0CDA_PORTL); 3531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds enable_dma(); 3541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (!(ar_inl(M32R_DMAEDET_PORTL) & 0x8000)) 3551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cpu_relax(); 3561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds disable_dma(); 3571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds clear_dma_status(); 3581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ar_outl(0xa0861300, M32R_DMA0CR0_PORTL); 3591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds local_irq_restore(flags); 3621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif /* ! USE_INT */ 3631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 3651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * convert YUV422 to YUV422P 3661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * +--------------------+ 3671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * | Y0,Y1,... | 3681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * | ..............Yn | 3691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * +--------------------+ 3701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * | U0,U1,........Un | 3711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * +--------------------+ 3721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * | V0,V1,........Vn | 3731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * +--------------------+ 3741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 3751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds py = yuv; 3761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pu = py + (ar->frame_bytes / 2); 3771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pv = pu + (ar->frame_bytes / 4); 3781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (h = 0; h < ar->height; h++) { 3791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p = ar->frame[h]; 3801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (w = 0; w < ar->line_bytes; w += 4) { 3811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *py++ = *p++; 3821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *pu++ = *p++; 3831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *py++ = *p++; 3841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *pv++ = *p++; 3851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (copy_to_user(buf, yuv, ar->frame_bytes)) { 388b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil v4l2_err(&ar->v4l2_dev, "failed while copy_to_user yuv.\n"); 3891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret = -EFAULT; 3901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out_up; 3911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DEBUG(1, "ret = %d\n", ret); 3931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsout_up: 3943593cab5d62c4c7abced1076710f9bc2d8847433Ingo Molnar mutex_unlock(&ar->lock); 3951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ret; 3961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 398b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuilstatic int ar_querycap(struct file *file, void *priv, 399b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil struct v4l2_capability *vcap) 4001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 401b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil struct ar *ar = video_drvdata(file); 402b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil 403b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil strlcpy(vcap->driver, ar->vdev.name, sizeof(vcap->driver)); 404b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil strlcpy(vcap->card, "Colour AR VGA", sizeof(vcap->card)); 405b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil strlcpy(vcap->bus_info, "Platform", sizeof(vcap->bus_info)); 406b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil vcap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE; 407b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil return 0; 408b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil} 409b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil 410b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuilstatic int ar_enum_input(struct file *file, void *fh, struct v4l2_input *vin) 411b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil{ 412b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil if (vin->index > 0) 4131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EINVAL; 414b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil strlcpy(vin->name, "Camera", sizeof(vin->name)); 415b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil vin->type = V4L2_INPUT_TYPE_CAMERA; 416b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil vin->audioset = 0; 417b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil vin->tuner = 0; 418b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil vin->std = V4L2_STD_ALL; 419b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil vin->status = 0; 420b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil return 0; 421b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil} 422b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil 423b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuilstatic int ar_g_input(struct file *file, void *fh, unsigned int *inp) 424b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil{ 425b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil *inp = 0; 426b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil return 0; 427b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil} 428b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil 429b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuilstatic int ar_s_input(struct file *file, void *fh, unsigned int inp) 430b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil{ 431b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil return inp ? -EINVAL : 0; 432b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil} 433b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil 434b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuilstatic int ar_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt) 435b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil{ 436b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil struct ar *ar = video_drvdata(file); 437b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil struct v4l2_pix_format *pix = &fmt->fmt.pix; 438b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil 439b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil pix->width = ar->width; 440b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil pix->height = ar->height; 441b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil pix->pixelformat = V4L2_PIX_FMT_YUV422P; 442b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil pix->field = (ar->mode == AR_MODE_NORMAL) ? V4L2_FIELD_NONE : V4L2_FIELD_INTERLACED; 443b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil pix->bytesperline = ar->width; 444b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil pix->sizeimage = 2 * ar->width * ar->height; 445b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil /* Just a guess */ 446b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil pix->colorspace = V4L2_COLORSPACE_SMPTE170M; 447b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil return 0; 448b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil} 449b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil 450b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuilstatic int ar_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt) 451b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil{ 452b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil struct ar *ar = video_drvdata(file); 453b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil struct v4l2_pix_format *pix = &fmt->fmt.pix; 454b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil 455b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil if (pix->height <= AR_HEIGHT_QVGA || pix->width <= AR_WIDTH_QVGA) { 456b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil pix->height = AR_HEIGHT_QVGA; 457b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil pix->width = AR_WIDTH_QVGA; 458b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil pix->field = V4L2_FIELD_INTERLACED; 459b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil } else { 460b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil pix->height = AR_HEIGHT_VGA; 461b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil pix->width = AR_WIDTH_VGA; 462b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil pix->field = vga_interlace ? V4L2_FIELD_INTERLACED : V4L2_FIELD_NONE; 4631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 464b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil pix->pixelformat = V4L2_PIX_FMT_YUV422P; 465b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil pix->bytesperline = ar->width; 466b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil pix->sizeimage = 2 * ar->width * ar->height; 467b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil /* Just a guess */ 468b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil pix->colorspace = V4L2_COLORSPACE_SMPTE170M; 469b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil return 0; 470b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil} 471b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil 472b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuilstatic int ar_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt) 473b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil{ 474b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil struct ar *ar = video_drvdata(file); 475b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil struct v4l2_pix_format *pix = &fmt->fmt.pix; 476b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil int ret = ar_try_fmt_vid_cap(file, fh, fmt); 477b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil 478b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil if (ret) 479b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil return ret; 480b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil mutex_lock(&ar->lock); 481b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil ar->width = pix->width; 482b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil ar->height = pix->height; 483b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil if (ar->width == AR_WIDTH_VGA) { 484b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil ar->size = AR_SIZE_VGA; 485b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil ar->frame_bytes = AR_FRAME_BYTES_VGA; 486b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil ar->line_bytes = AR_LINE_BYTES_VGA; 487b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil if (vga_interlace) 4881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ar->mode = AR_MODE_INTERLACE; 489b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil else 490b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil ar->mode = AR_MODE_NORMAL; 491b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil } else { 492b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil ar->size = AR_SIZE_QVGA; 493b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil ar->frame_bytes = AR_FRAME_BYTES_QVGA; 494b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil ar->line_bytes = AR_LINE_BYTES_QVGA; 495b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil ar->mode = AR_MODE_INTERLACE; 4961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 497b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil /* Ok we figured out what to use from our wide choice */ 498b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil mutex_unlock(&ar->lock); 4991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 5001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 502b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuilstatic int ar_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc *fmt) 5031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 504b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil static struct v4l2_fmtdesc formats[] = { 505b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil { 0, 0, 0, 506b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil "YUV 4:2:2 Planar", V4L2_PIX_FMT_YUV422P, 507b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil { 0, 0, 0, 0 } 508b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil }, 509b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil }; 510b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil enum v4l2_buf_type type = fmt->type; 511b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil 512b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil if (fmt->index > 0) 513b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil return -EINVAL; 514b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil 515b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil *fmt = formats[fmt->index]; 516b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil fmt->type = type; 517b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil return 0; 5181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#if USE_INT 5211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 5221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Interrupt handler 5231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 5247d12e780e003f93433d49ce78cfedf4b4c52adc5David Howellsstatic void ar_interrupt(int irq, void *dev) 5251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 526b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil struct ar *ar = dev; 5271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int line_count; 5281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int line_number; 5291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int arvcr1; 5301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds line_count = ar_inl(ARVHCOUNT); /* line number */ 5321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ar->mode == AR_MODE_INTERLACE && ar->size == AR_SIZE_VGA) { 5331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* operations for interlace mode */ 53488f4423454a23375f07bb4ff3a80d209930560d0Hans Verkuil if (line_count < (AR_HEIGHT_VGA / 2)) /* even line */ 5351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds line_number = (line_count << 1); 536d56410e0a594150c5ca06319da7bc8901c4d455eMauro Carvalho Chehab else /* odd line */ 537d56410e0a594150c5ca06319da7bc8901c4d455eMauro Carvalho Chehab line_number = 53888f4423454a23375f07bb4ff3a80d209930560d0Hans Verkuil (((line_count - (AR_HEIGHT_VGA / 2)) << 1) + 1); 5391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 5401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds line_number = line_count; 5411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (line_number == 0) { 5441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 5451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * It is an interrupt for line 0. 5461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * we have to start capture. 5471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 5481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds disable_dma(); 5491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#if 0 5501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ar_outl(ar->line_buff, M32R_DMA0CDA_PORTL); /* needless? */ 5511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 5521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(ar->frame[0], ar->line_buff, ar->line_bytes); 5531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#if 0 5541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ar_outl(0xa1861300, M32R_DMA0CR0_PORTL); 5551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 5561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds enable_dma(); 5571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ar->start_capture = 1; /* during capture */ 5581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 5591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ar->start_capture == 1 && line_number <= (ar->height - 1)) { 5621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds disable_dma(); 5631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(ar->frame[line_number], ar->line_buff, ar->line_bytes); 5641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 5661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * if captured all line of a frame, disable AR interrupt 5671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * and wake a process up. 5681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 5691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (line_number == (ar->height - 1)) { /* end of line */ 5701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ar->start_capture = 0; 5721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* disable AR interrupt request */ 5741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds arvcr1 = ar_inl(ARVCR1); 5751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds arvcr1 &= ~ARVCR1_HIEN; /* clear int. flag */ 5761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ar_outl(arvcr1, ARVCR1); /* disable */ 5771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds wake_up_interruptible(&ar->wait); 5781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 5791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#if 0 5801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ar_outl(ar->line_buff, M32R_DMA0CDA_PORTL); 5811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ar_outl(0xa1861300, M32R_DMA0CR0_PORTL); 5821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 5831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds enable_dma(); 5841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 5881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 5901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * ar_initialize() 5911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * ar_initialize() is called by video_register_device() and 5921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * initializes AR LSI and peripherals. 5931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 5941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * -1 is returned in all failures. 5951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 0 is returned in success. 5961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 5971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 598b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuilstatic int ar_initialize(struct ar *ar) 5991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long cr = 0; 60188f4423454a23375f07bb4ff3a80d209930560d0Hans Verkuil int i, found = 0; 6021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DEBUG(1, "ar_initialize:\n"); 6041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 6061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * initialize AR LSI 6071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 6081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ar_outl(0, ARVCR0); /* assert reset of AR LSI */ 6091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < 0x18; i++) /* wait for over 10 cycles @ 27MHz */ 6101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cpu_relax(); 6111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ar_outl(ARVCR0_RST, ARVCR0); /* negate reset of AR LSI (enable) */ 6121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < 0x40d; i++) /* wait for over 420 cycles @ 27MHz */ 6131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cpu_relax(); 6141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* AR uses INT3 of CPU as interrupt pin. */ 6161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ar_outl(ARINTSEL_INT3, ARINTSEL); 6171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ar->size == AR_SIZE_QVGA) 6191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cr |= ARVCR1_QVGA; 6201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ar->mode == AR_MODE_NORMAL) 6211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cr |= ARVCR1_NORMAL; 6221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ar_outl(cr, ARVCR1); 6231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 624d56410e0a594150c5ca06319da7bc8901c4d455eMauro Carvalho Chehab /* 6251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Initialize IIC so that CPU can communicate with AR LSI, 6261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * and send boot commands to AR LSI. 6271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 6281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds init_iic(); 6291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < 0x100000; i++) { /* > 0xa1d10, 56ms */ 6311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((ar_inl(ARVCR0) & ARVCR0_VDS)) { /* VSYNC */ 6321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds found = 1; 6331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 6341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (found == 0) 6381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -ENODEV; 6391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 640b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil v4l2_info(&ar->v4l2_dev, "Initializing "); 64188f4423454a23375f07bb4ff3a80d209930560d0Hans Verkuil 64288f4423454a23375f07bb4ff3a80d209930560d0Hans Verkuil iic(2, 0x78, 0x11, 0x01, 0x00); /* start */ 64388f4423454a23375f07bb4ff3a80d209930560d0Hans Verkuil iic(3, 0x78, 0x12, 0x00, 0x06); 64488f4423454a23375f07bb4ff3a80d209930560d0Hans Verkuil iic(3, 0x78, 0x12, 0x12, 0x30); 64588f4423454a23375f07bb4ff3a80d209930560d0Hans Verkuil iic(3, 0x78, 0x12, 0x15, 0x58); 64688f4423454a23375f07bb4ff3a80d209930560d0Hans Verkuil iic(3, 0x78, 0x12, 0x17, 0x30); 64788f4423454a23375f07bb4ff3a80d209930560d0Hans Verkuil printk(KERN_CONT "."); 64888f4423454a23375f07bb4ff3a80d209930560d0Hans Verkuil iic(3, 0x78, 0x12, 0x1a, 0x97); 64988f4423454a23375f07bb4ff3a80d209930560d0Hans Verkuil iic(3, 0x78, 0x12, 0x1b, 0xff); 65088f4423454a23375f07bb4ff3a80d209930560d0Hans Verkuil iic(3, 0x78, 0x12, 0x1c, 0xff); 65188f4423454a23375f07bb4ff3a80d209930560d0Hans Verkuil iic(3, 0x78, 0x12, 0x26, 0x10); 65288f4423454a23375f07bb4ff3a80d209930560d0Hans Verkuil iic(3, 0x78, 0x12, 0x27, 0x00); 65388f4423454a23375f07bb4ff3a80d209930560d0Hans Verkuil printk(KERN_CONT "."); 65488f4423454a23375f07bb4ff3a80d209930560d0Hans Verkuil iic(2, 0x78, 0x34, 0x02, 0x00); 65588f4423454a23375f07bb4ff3a80d209930560d0Hans Verkuil iic(2, 0x78, 0x7a, 0x10, 0x00); 65688f4423454a23375f07bb4ff3a80d209930560d0Hans Verkuil iic(2, 0x78, 0x80, 0x39, 0x00); 65788f4423454a23375f07bb4ff3a80d209930560d0Hans Verkuil iic(2, 0x78, 0x81, 0xe6, 0x00); 65888f4423454a23375f07bb4ff3a80d209930560d0Hans Verkuil iic(2, 0x78, 0x8d, 0x00, 0x00); 65988f4423454a23375f07bb4ff3a80d209930560d0Hans Verkuil printk(KERN_CONT "."); 66088f4423454a23375f07bb4ff3a80d209930560d0Hans Verkuil iic(2, 0x78, 0x8e, 0x0c, 0x00); 66188f4423454a23375f07bb4ff3a80d209930560d0Hans Verkuil iic(2, 0x78, 0x8f, 0x00, 0x00); 6621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#if 0 66388f4423454a23375f07bb4ff3a80d209930560d0Hans Verkuil iic(2, 0x78, 0x90, 0x00, 0x00); /* AWB on=1 off=0 */ 6641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 66588f4423454a23375f07bb4ff3a80d209930560d0Hans Verkuil iic(2, 0x78, 0x93, 0x01, 0x00); 66688f4423454a23375f07bb4ff3a80d209930560d0Hans Verkuil iic(2, 0x78, 0x94, 0xcd, 0x00); 66788f4423454a23375f07bb4ff3a80d209930560d0Hans Verkuil iic(2, 0x78, 0x95, 0x00, 0x00); 66888f4423454a23375f07bb4ff3a80d209930560d0Hans Verkuil printk(KERN_CONT "."); 66988f4423454a23375f07bb4ff3a80d209930560d0Hans Verkuil iic(2, 0x78, 0x96, 0xa0, 0x00); 67088f4423454a23375f07bb4ff3a80d209930560d0Hans Verkuil iic(2, 0x78, 0x97, 0x00, 0x00); 67188f4423454a23375f07bb4ff3a80d209930560d0Hans Verkuil iic(2, 0x78, 0x98, 0x60, 0x00); 67288f4423454a23375f07bb4ff3a80d209930560d0Hans Verkuil iic(2, 0x78, 0x99, 0x01, 0x00); 67388f4423454a23375f07bb4ff3a80d209930560d0Hans Verkuil iic(2, 0x78, 0x9a, 0x19, 0x00); 67488f4423454a23375f07bb4ff3a80d209930560d0Hans Verkuil printk(KERN_CONT "."); 67588f4423454a23375f07bb4ff3a80d209930560d0Hans Verkuil iic(2, 0x78, 0x9b, 0x02, 0x00); 67688f4423454a23375f07bb4ff3a80d209930560d0Hans Verkuil iic(2, 0x78, 0x9c, 0xe8, 0x00); 67788f4423454a23375f07bb4ff3a80d209930560d0Hans Verkuil iic(2, 0x78, 0x9d, 0x02, 0x00); 67888f4423454a23375f07bb4ff3a80d209930560d0Hans Verkuil iic(2, 0x78, 0x9e, 0x2e, 0x00); 67988f4423454a23375f07bb4ff3a80d209930560d0Hans Verkuil iic(2, 0x78, 0xb8, 0x78, 0x00); 68088f4423454a23375f07bb4ff3a80d209930560d0Hans Verkuil iic(2, 0x78, 0xba, 0x05, 0x00); 6811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#if 0 68288f4423454a23375f07bb4ff3a80d209930560d0Hans Verkuil iic(2, 0x78, 0x83, 0x8c, 0x00); /* brightness */ 6831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 68488f4423454a23375f07bb4ff3a80d209930560d0Hans Verkuil printk(KERN_CONT "."); 6851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* color correction */ 68788f4423454a23375f07bb4ff3a80d209930560d0Hans Verkuil iic(3, 0x78, 0x49, 0x00, 0x95); /* a */ 68888f4423454a23375f07bb4ff3a80d209930560d0Hans Verkuil iic(3, 0x78, 0x49, 0x01, 0x96); /* b */ 68988f4423454a23375f07bb4ff3a80d209930560d0Hans Verkuil iic(3, 0x78, 0x49, 0x03, 0x85); /* c */ 69088f4423454a23375f07bb4ff3a80d209930560d0Hans Verkuil iic(3, 0x78, 0x49, 0x04, 0x97); /* d */ 69188f4423454a23375f07bb4ff3a80d209930560d0Hans Verkuil iic(3, 0x78, 0x49, 0x02, 0x7e); /* e(Lo) */ 69288f4423454a23375f07bb4ff3a80d209930560d0Hans Verkuil iic(3, 0x78, 0x49, 0x05, 0xa4); /* f(Lo) */ 69388f4423454a23375f07bb4ff3a80d209930560d0Hans Verkuil iic(3, 0x78, 0x49, 0x06, 0x04); /* e(Hi) */ 69488f4423454a23375f07bb4ff3a80d209930560d0Hans Verkuil iic(3, 0x78, 0x49, 0x07, 0x04); /* e(Hi) */ 69588f4423454a23375f07bb4ff3a80d209930560d0Hans Verkuil iic(2, 0x78, 0x48, 0x01, 0x00); /* on=1 off=0 */ 69688f4423454a23375f07bb4ff3a80d209930560d0Hans Verkuil 69788f4423454a23375f07bb4ff3a80d209930560d0Hans Verkuil printk(KERN_CONT "."); 69888f4423454a23375f07bb4ff3a80d209930560d0Hans Verkuil iic(2, 0x78, 0x11, 0x00, 0x00); /* end */ 69988f4423454a23375f07bb4ff3a80d209930560d0Hans Verkuil printk(KERN_CONT " done\n"); 7001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 7011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/**************************************************************************** 7051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 7061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Video4Linux Module functions 7071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 7081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ****************************************************************************/ 7097d43cd53c851e3cf04d73108d4e7e25a1104c6f5Hans Verkuil 710bec43661b1dc0075b7445223ba775674133b164dHans Verkuilstatic const struct v4l2_file_operations ar_fops = { 7111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .owner = THIS_MODULE, 7121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .read = ar_read, 71361df3c9b3fe6a7e47d25b27ae4df0ecdb07b8fbdHans Verkuil .unlocked_ioctl = video_ioctl2, 7141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 7151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 716b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuilstatic const struct v4l2_ioctl_ops ar_ioctl_ops = { 717b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil .vidioc_querycap = ar_querycap, 718b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil .vidioc_g_input = ar_g_input, 719b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil .vidioc_s_input = ar_s_input, 720b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil .vidioc_enum_input = ar_enum_input, 721b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil .vidioc_enum_fmt_vid_cap = ar_enum_fmt_vid_cap, 722b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil .vidioc_g_fmt_vid_cap = ar_g_fmt_vid_cap, 723b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil .vidioc_s_fmt_vid_cap = ar_s_fmt_vid_cap, 724b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil .vidioc_try_fmt_vid_cap = ar_try_fmt_vid_cap, 7251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 7261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define ALIGN4(x) ((((int)(x)) & 0x3) == 0) 7281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int __init ar_init(void) 7301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 731b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil struct ar *ar; 732b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil struct v4l2_device *v4l2_dev; 7331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int ret; 7341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 7351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ar = &ardev; 737b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil v4l2_dev = &ar->v4l2_dev; 738b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil strlcpy(v4l2_dev->name, "arv", sizeof(v4l2_dev->name)); 739b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil v4l2_info(v4l2_dev, "Colour AR VGA driver %s\n", VERSION); 740b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil 741b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil ret = v4l2_device_register(NULL, v4l2_dev); 742b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil if (ret < 0) { 743b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil v4l2_err(v4l2_dev, "Could not register v4l2_device\n"); 744b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil return ret; 745b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil } 746b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil ret = -EIO; 7471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#if USE_INT 7491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* allocate a DMA buffer for 1 line. */ 7501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ar->line_buff = kmalloc(MAX_AR_LINE_BYTES, GFP_KERNEL | GFP_DMA); 75188f4423454a23375f07bb4ff3a80d209930560d0Hans Verkuil if (ar->line_buff == NULL || !ALIGN4(ar->line_buff)) { 752b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil v4l2_err(v4l2_dev, "buffer allocation failed for DMA.\n"); 7531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret = -ENOMEM; 7541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out_end; 7551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 7571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* allocate buffers for a frame */ 7581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < MAX_AR_HEIGHT; i++) { 7591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ar->frame[i] = kmalloc(MAX_AR_LINE_BYTES, GFP_KERNEL); 76088f4423454a23375f07bb4ff3a80d209930560d0Hans Verkuil if (ar->frame[i] == NULL || !ALIGN4(ar->frame[i])) { 761b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil v4l2_err(v4l2_dev, "buffer allocation failed for frame.\n"); 7621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret = -ENOMEM; 7631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out_line_buff; 7641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 767b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil strlcpy(ar->vdev.name, "Colour AR VGA", sizeof(ar->vdev.name)); 768b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil ar->vdev.v4l2_dev = v4l2_dev; 769b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil ar->vdev.fops = &ar_fops; 770b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil ar->vdev.ioctl_ops = &ar_ioctl_ops; 771b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil ar->vdev.release = video_device_release_empty; 772b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil video_set_drvdata(&ar->vdev, ar); 7731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (vga) { 7751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ar->width = AR_WIDTH_VGA; 7761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ar->height = AR_HEIGHT_VGA; 7771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ar->size = AR_SIZE_VGA; 7781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ar->frame_bytes = AR_FRAME_BYTES_VGA; 7791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ar->line_bytes = AR_LINE_BYTES_VGA; 7801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (vga_interlace) 7811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ar->mode = AR_MODE_INTERLACE; 7821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 7831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ar->mode = AR_MODE_NORMAL; 7841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 7851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ar->width = AR_WIDTH_QVGA; 7861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ar->height = AR_HEIGHT_QVGA; 7871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ar->size = AR_SIZE_QVGA; 7881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ar->frame_bytes = AR_FRAME_BYTES_QVGA; 7891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ar->line_bytes = AR_LINE_BYTES_QVGA; 7901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ar->mode = AR_MODE_INTERLACE; 7911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7923593cab5d62c4c7abced1076710f9bc2d8847433Ingo Molnar mutex_init(&ar->lock); 7931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds init_waitqueue_head(&ar->wait); 7941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#if USE_INT 7961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (request_irq(M32R_IRQ_INT3, ar_interrupt, 0, "arv", ar)) { 797b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil v4l2_err("request_irq(%d) failed.\n", M32R_IRQ_INT3); 7981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret = -EIO; 7991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out_irq; 8001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 8021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 803b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil if (ar_initialize(ar) != 0) { 804b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil v4l2_err(v4l2_dev, "M64278 not found.\n"); 8051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret = -ENODEV; 8061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out_dev; 8071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 8101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * ok, we can initialize h/w according to parameters, 8111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * so register video device as a frame grabber type. 8121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * device is named "video[0-64]". 8131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * video_register_device() initializes h/w using ar_initialize(). 814d56410e0a594150c5ca06319da7bc8901c4d455eMauro Carvalho Chehab */ 815b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil if (video_register_device(&ar->vdev, VFL_TYPE_GRABBER, video_nr) != 0) { 8161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* return -1, -ENFILE(full) or others */ 817b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil v4l2_err(v4l2_dev, "register video (Colour AR) failed.\n"); 8181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret = -ENODEV; 8191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out_dev; 8201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 822b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil v4l2_info(v4l2_dev, "%s: Found M64278 VGA (IRQ %d, Freq %dMHz).\n", 823b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil video_device_node_name(&ar->vdev), M32R_IRQ_INT3, freq); 8241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 8261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsout_dev: 8281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#if USE_INT 8291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds free_irq(M32R_IRQ_INT3, ar); 8301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsout_irq: 8321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 8332ea7533060e361810c21b2f5ee02151c4dfb85d8Jesper Juhl for (i = 0; i < MAX_AR_HEIGHT; i++) 8342ea7533060e361810c21b2f5ee02151c4dfb85d8Jesper Juhl kfree(ar->frame[i]); 8351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsout_line_buff: 8371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#if USE_INT 8381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds kfree(ar->line_buff); 8391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsout_end: 8411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 842b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil v4l2_device_unregister(&ar->v4l2_dev); 8431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ret; 8441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int __init ar_init_module(void) 8481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 8491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds freq = (boot_cpu_data.bus_clock / 1000000); 85088f4423454a23375f07bb4ff3a80d209930560d0Hans Verkuil printk(KERN_INFO "arv: Bus clock %d\n", freq); 8511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (freq != 50 && freq != 75) 8521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds freq = DEFAULT_FREQ; 8531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ar_init(); 8541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void __exit ar_cleanup_module(void) 8571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 858b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil struct ar *ar; 8591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 8601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ar = &ardev; 862b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil video_unregister_device(&ar->vdev); 8631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#if USE_INT 8641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds free_irq(M32R_IRQ_INT3, ar); 8651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 8662ea7533060e361810c21b2f5ee02151c4dfb85d8Jesper Juhl for (i = 0; i < MAX_AR_HEIGHT; i++) 8672ea7533060e361810c21b2f5ee02151c4dfb85d8Jesper Juhl kfree(ar->frame[i]); 8681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#if USE_INT 8691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds kfree(ar->line_buff); 8701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 871b8e56b6f6e5b6c55d4d375cc9ebd79151b44db58Hans Verkuil v4l2_device_unregister(&ar->v4l2_dev); 8721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodule_init(ar_init_module); 8751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodule_exit(ar_cleanup_module); 8761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_AUTHOR("Takeo Takahashi <takahashi.takeo@renesas.com>"); 8781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_DESCRIPTION("Colour AR M64278(VGA) for Video4Linux"); 8791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_LICENSE("GPL"); 8801990d50b58bef127a647005fdcada6d07081d3efMauro Carvalho ChehabMODULE_VERSION(VERSION); 881